API referenceAdmin APIFederation issuersRegister an issuer

Register an issuer

⚠️
Preview — this feature is being built; the design below is the spec.
POST https://app.syntic.ai/v1/organizations/federation/issuers

Register 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

HeaderRequiredValue
AuthorizationYesBearer <admin key>: an Admin API key (sk_admin_...). Inference keys are refused with 403 admin_key_required. See Admin API keys.
syntic-betaYes, while in previewadmin-2026-11-01. Without it the call fails with 400 beta_required. See Versioning.
Content-TypeYesapplication/json
Idempotency-KeyNoUp to 255 characters. Retrying with the same key within 24 hours returns the first result instead of acting twice. See Idempotency.

Body parameters

ParameterTypeRequiredNotes
issuerstringYesHTTPS URL.
display_namestringNoUp to 64 characters.
jwks_uristringNoSet only when the issuer has no discovery document; switches discovery to static.
allowed_algorithmsarray of stringsNoDefault ["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"
}
FieldTypeDescription
issuerstringMust match the iss claim exactly, including scheme and no trailing slash.
jwks_uristringWhere signing keys are fetched. Found through OIDC discovery unless set by hand.
discoverystringoidc (keys located through /.well-known/openid-configuration) or static (jwks_uri given directly).
allowed_algorithmsarraySignature algorithms accepted. none and HMAC algorithms are never accepted.
statusstringverified once keys were fetched, unreachable if the last three refreshes failed.
keys_refreshed_atstringKeys 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:

StatustypecodeWhen
400invalid_request_errorbeta_requiredThe syntic-beta header is missing.
400invalid_request_errorissuer_unreachableDiscovery or key download failed; the message says which step.
400invalid_request_errorprivate_addressThe issuer resolves to a private or loopback address.
409conflict_errorissuer_existsAlready registered, or a preset.
401authentication_errorinvalid_api_keyThe admin key is missing, unknown, revoked or expired.
403permission_erroradmin_key_requiredAn inference key was used.
429rate_limit_errorrate_limitedToo many requests; wait for Retry-After. See Rate-limit headers.
Was this page helpful?