Portal API

Self-service API for managing keys, providers, and settings.

Managed service only

Portal endpoints are available in managed/cloud mode only. For self-hosted standalone deployments, configure settings via environment variables.

Authentication

Portal endpoints require a valid JWT access token. Obtain tokens through the login flow, then include the access token in the Authorization header for all portal requests.

Base path: /portal

POST /auth/login

Authenticate with email and password. Returns an access token (15-minute expiry) and a refresh token (7-day expiry).

curl -X POST https://api.noirdoc.de/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "your-password"
  }'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
}

POST /auth/refresh

Exchange a valid refresh token for a new access token when the current one expires.

curl -X POST https://api.noirdoc.de/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
  }'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs..."
}

POST /auth/logout

Invalidate the current refresh token. The access token remains valid until it expires naturally.

curl -X POST https://api.noirdoc.de/auth/logout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Using the access token

Include the access token in the Authorization header for all subsequent portal requests:

Authorization: Bearer <access_token>

API keys

GET /portal/keys

List all proxy API keys for the current tenant.

curl https://api.noirdoc.de/portal/keys \
  -H "Authorization: Bearer <access_token>"

Response:

[
  {
    "id": "key_abc123",
    "label": "production",
    "prefix": "px-a1b2",
    "created_at": "2025-09-15T10:30:00Z",
    "is_active": true
  },
  {
    "id": "key_def456",
    "label": "staging",
    "prefix": "px-c3d4",
    "created_at": "2025-10-01T08:00:00Z",
    "is_active": true
  }
]

POST /portal/keys

Create a new proxy API key. The full key value is returned only once in the response — store it securely.

curl -X POST https://api.noirdoc.de/portal/keys \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"label": "new-service-key"}'

Request body:

FieldTypeRequiredDescription
labelstringYesA human-readable label for the key

Response:

{
  "id": "key_ghi789",
  "label": "new-service-key",
  "key": "px-full-key-value-shown-only-once",
  "created_at": "2025-11-20T14:00:00Z"
}

PATCH /portal/keys/{id}

Update a key’s properties, such as its label.

curl -X PATCH https://api.noirdoc.de/portal/keys/key_abc123 \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"label": "renamed-key"}'

DELETE /portal/keys/{id}

Soft-delete a key. The key is deactivated and can no longer be used for proxy requests. It can be reactivated later.

curl -X DELETE https://api.noirdoc.de/portal/keys/key_abc123 \
  -H "Authorization: Bearer <access_token>"

POST /portal/keys/{id}/reactivate

Reactivate a previously deleted key.

curl -X POST https://api.noirdoc.de/portal/keys/key_abc123/reactivate \
  -H "Authorization: Bearer <access_token>"

Providers

GET /portal/providers

List all configured LLM providers for the current tenant.

curl https://api.noirdoc.de/portal/providers \
  -H "Authorization: Bearer <access_token>"

Response:

[
  {
    "provider": "openai",
    "provider_type": "openai",
    "base_url": "https://api.openai.com/v1",
    "has_api_key": true
  }
]

PUT /portal/providers/{provider}

Configure or update a provider. This sets the API key and connection details that Noirdoc uses when forwarding requests to this provider.

curl -X PUT https://api.noirdoc.de/portal/providers/openai \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "sk-your-openai-key",
    "provider_type": "openai"
  }'

Request body:

FieldTypeRequiredDescription
api_keystringYesThe provider’s API key
base_urlstringNoCustom base URL (for Azure or self-hosted)
api_versionstringNoAPI version (for Azure OpenAI)
provider_typestringYesProvider type: openai, anthropic, azure, openrouter

DELETE /portal/providers/{provider}

Remove a provider configuration. Proxy requests that require this provider will fail until it is reconfigured.

curl -X DELETE https://api.noirdoc.de/portal/providers/openai \
  -H "Authorization: Bearer <access_token>"

Settings

GET /portal/settings

Retrieve the current tenant’s settings, including pseudonymization behavior, mapping TTL, file handling mode, and more.

curl https://api.noirdoc.de/portal/settings \
  -H "Authorization: Bearer <access_token>"

PATCH /portal/settings

Update one or more settings. Only include the fields you want to change.

curl -X PATCH https://api.noirdoc.de/portal/settings \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "mapping_ttl_days": 14,
    "file_handling": "block"
  }'

Usage and audit logs

GET /portal/usage

Retrieve usage statistics for the current tenant, including request counts and token usage.

curl https://api.noirdoc.de/portal/usage \
  -H "Authorization: Bearer <access_token>"

GET /portal/audit-logs

Retrieve audit logs for the current tenant. Supports filtering by date range and event type via query parameters.

curl "https://api.noirdoc.de/portal/audit-logs?from=2025-11-01&to=2025-11-30" \
  -H "Authorization: Bearer <access_token>"

Error responses

Portal endpoints return standard HTTP error codes:

StatusMeaning
401Missing or invalid JWT token
403Insufficient permissions
404Resource not found
422Validation error — check the request body