Register an issuer
⚠️
Preview — this feature is being built; the design below is the spec.
POST https://app.syntic.ai/v1/organizations/federation/issuersRegister an OIDC issuer that is not one of the presets, such as a self-managed CI server or a private cluster. Syntic fetches the issuer’s keys straight away and refuses the registration if it cannot. Preset issuers (the public CI and cloud providers) need no registration.
For how this fits into a full workflow, see Workload identity.
Headers
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer <admin key>: an Admin API key (sk_admin_...). Inference keys are refused with 403 admin_key_required. See Admin API keys. |
syntic-beta | Yes, while in preview | admin-2026-11-01. Without it the call fails with 400 beta_required. See Versioning. |
Content-Type | Yes | application/json |
Idempotency-Key | No | Up to 255 characters. Retrying with the same key within 24 hours returns the first result instead of acting twice. See Idempotency. |
Body parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
issuer | string | Yes | HTTPS URL. |
display_name | string | No | Up to 64 characters. |
jwks_uri | string | No | Set only when the issuer has no discovery document; switches discovery to static. |
allowed_algorithms | array of strings | No | Default ["RS256", "ES256"]. Also allowed: RS384, RS512, ES384, PS256, EdDSA. |
Response
201 Created, Content-Type: application/json
{
"id": "fiss_01JCJ8L0N2Q4S6U8W0Y2",
"type": "federation_issuer",
"issuer": "https://gitlab.internal.example.com",
"display_name": "Self-managed GitLab",
"jwks_uri": "https://gitlab.internal.example.com/oauth/discovery/keys",
"discovery": "oidc",
"allowed_algorithms": [
"RS256",
"ES256"
],
"status": "verified",
"keys_refreshed_at": "2026-11-05T09:00:00Z",
"created_at": "2026-10-18T12:00:00Z"
}| Field | Type | Description |
|---|---|---|
issuer | string | Must match the iss claim exactly, including scheme and no trailing slash. |
jwks_uri | string | Where signing keys are fetched. Found through OIDC discovery unless set by hand. |
discovery | string | oidc (keys located through /.well-known/openid-configuration) or static (jwks_uri given directly). |
allowed_algorithms | array | Signature algorithms accepted. none and HMAC algorithms are never accepted. |
status | string | verified once keys were fetched, unreachable if the last three refreshes failed. |
keys_refreshed_at | string | Keys are refreshed hourly and on an unknown kid. |
Examples
curl -sS "https://app.syntic.ai/v1/organizations/federation/issuers" \
-H "Authorization: Bearer $SYNTIC_ADMIN_KEY" \
-H "syntic-beta: admin-2026-11-01" \
-H "Idempotency-Key: 8d6f0c1e-4b2a-4a57-9f0e-2f1d3c4b5a69" \
-H "Content-Type: application/json" \
-d '{
"issuer": "https://gitlab.internal.example.com",
"display_name": "Self-managed GitLab"
}'Errors
Errors use the error envelope and carry a request_id. Codes specific to this operation:
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request_error | beta_required | The syntic-beta header is missing. |
| 400 | invalid_request_error | issuer_unreachable | Discovery or key download failed; the message says which step. |
| 400 | invalid_request_error | private_address | The issuer resolves to a private or loopback address. |
| 409 | conflict_error | issuer_exists | Already registered, or a preset. |
| 401 | authentication_error | invalid_api_key | The admin key is missing, unknown, revoked or expired. |
| 403 | permission_error | admin_key_required | An inference key was used. |
| 429 | rate_limit_error | rate_limited | Too many requests; wait for Retry-After. See Rate-limit headers. |
Was this page helpful?