---
title: "Create provider"
method: POST
path: "/zones/{zoneId}/providers"
tags: ["Providers"]
---

# Create provider

`POST /zones/{zoneId}/providers`

## Request

- Base URL: `https://docs.keycard.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://docs.keycard.ai/zones/{zoneId}/providers`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Client credentials
    - Token URL: `/service-account-token`

Creates a new Provider - a system that supplies access to Resources and allows actors to authenticate

## Path parameters

- `zoneId` string, required

## Request body

- IamProviderCreate: Schema for creating a new provider
  - `name` string, safe-text, required: Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
  - `description` string, safe-text, nullable: Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
  - `identifier` string, safe-text, required: User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
  - `client_id` string: OAuth 2.0 client identifier
  - `client_secret` string: OAuth 2.0 client secret (will be encrypted and stored securely)
  - `protocols` IamProviderProtocolCreate: Protocol-specific configuration for provider creation
    - `oauth2` IamProviderOAuth2ProtocolCreate: OAuth 2.0 protocol configuration for provider creation
      - `issuer` string, uri: OIDC issuer URL for discovery and token validation. When omitted, the provider identifier is used as the issuer. New clients should always set this explicitly.
      - `authorization_endpoint` string, uri
      - `token_endpoint` string, uri
      - `registration_endpoint` string, uri
      - `jwks_uri` string, uri
      - `code_challenge_methods_supported` string[]
      - `scopes_supported` string[]
      - `authorization_resource_enabled` boolean: Whether to include the resource parameter in authorization requests.
      - `authorization_resource_parameter` string: The resource parameter value to include in authorization requests. Defaults to "resource" when authorization_resource_enabled is true.
      - `scope_parameter` string: The query parameter name for scopes in authorization requests. Defaults to "scope". Slack v2 uses "user_scope".
      - `scope_separator` string: The separator character for scope values. Defaults to " " (space). Slack v2 uses ",".
      - `token_response_access_token_pointer` string: Dot-separated path to the access token in the token response body. Defaults to "access_token". Slack v2 uses "authed_user.access_token".
      - `authorization_parameters` object: Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline).
    - `openid` IamProviderOpenIDProtocolCreate: OpenID Connect protocol configuration for provider creation
      - `userinfo_endpoint` string, uri
      - `user_identifier_claim` string: Name of a top-level string claim in this provider's ID Token to use as the user identifier on user creation. When not set, the user's Keycard ID is used.
      - `scopes` string[]: Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email).
      - `single_logout_enabled` boolean: When true, logging out of the zone propagates the logout to this provider's end_session_endpoint (RP-initiated logout). Defaults to false.
  - `metadata` object: Provider metadata
    - `icon_url` string, uri: Icon URL

## Response `200`

A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.

- IamProvider: A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
  - `id` string, required: Unique identifier of the provider
  - `organization_id` string, required: Organization that owns this provider
  - `zone_id` string, required: Zone this provider belongs to
  - `slug` string, required: URL-safe identifier, unique within the zone
  - `name` string, required: Human-readable name
  - `description` string, nullable: Human-readable description
  - `identifier` string, required: User specified identifier, unique within the zone
  - `type` 'external' | 'keycard-vault' | 'keycard-sts'
  - `client_id` string, nullable: OAuth 2.0 client identifier
  - `client_secret_set` boolean: Indicates whether a client secret is configured
  - `protocols` object, nullable: Protocol-specific configuration
    - `oauth2` IamProviderOAuth2Protocol, nullable: OAuth 2.0 protocol configuration
      - `issuer` string, uri, required: OIDC issuer URL used for discovery and token validation.
      - `authorization_endpoint` string, uri, nullable
      - `token_endpoint` string, uri, nullable
      - `registration_endpoint` string, uri, nullable
      - `jwks_uri` string, uri, nullable
      - `code_challenge_methods_supported` string[], nullable
      - `scopes_supported` string[], nullable
      - `authorization_resource_enabled` boolean, nullable: Whether to include the resource parameter in authorization requests.
      - `authorization_resource_parameter` string, nullable: The resource parameter value to include in authorization requests. Defaults to "resource" when authorization_resource_enabled is true.
      - `scope_parameter` string, nullable: The query parameter name for scopes in authorization requests. Defaults to "scope". Slack v2 uses "user_scope".
      - `scope_separator` string, nullable: The separator character for scope values. Defaults to " " (space). Slack v2 uses ",".
      - `token_response_access_token_pointer` string, nullable: Dot-separated path to the access token in the token response body. Defaults to "access_token". Slack v2 uses "authed_user.access_token".
      - `authorization_parameters` object, nullable: Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline).
    - `openid` IamProviderOpenIDProtocol, nullable: OpenID Connect protocol configuration
      - `userinfo_endpoint` string, uri, nullable
      - `user_identifier_claim` string, nullable: Name of a top-level string claim in this provider's ID Token to use as the user identifier on user creation. When not set, the user's Keycard ID is used.
      - `scopes` string[], nullable: Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email).
      - `single_logout_enabled` boolean, nullable: When true, logging out of the zone propagates the logout to this provider's end_session_endpoint (RP-initiated logout). Defaults to false.
  - `metadata` object, nullable: Provider metadata
    - `icon_url` string, uri: Icon URL
  - `owner_type` 'platform' | 'customer', required: Who owns this provider. Platform-owned providers cannot be modified via API.
  - `created_at` string, date-time, required: Entity creation timestamp
  - `updated_at` string, date-time, required: Entity update timestamp

## Other responses

- `400`: Error response
- `403`: Error response
- `default`: Error response

## Changes

- **2026-10-16** `0cfaff865771`: 2 warning
  - removed the request property `protocols/openid/external_id_claim`
  - removed the optional property `protocols/openid/external_id_claim` from the response with the `200` status
- **2026-08-26** `d65d51379d93`: 6 info
  - added the new optional request property `metadata/icon_url`
  - added the new optional request property `protocols/openid/external_id_claim`
  - added the non-success response with the status `400`
  - added the non-success response with the status `403`
  - …2 more
- **2026-07-01** `2f5033ed4491`: 2 info
  - added the new optional request property `protocols/openid/single_logout_enabled`
  - added the optional property `protocols/openid/single_logout_enabled` to the response with the `200` status
- **2026-05-22** `ffb6f697525f`: 2 info
  - added the new optional request property `protocols/openid/scopes`
  - added the optional property `protocols/openid/scopes` to the response with the `200` status
- **2026-04-20** `932699a5ea16`: 3 breaking
  - the `description` request property format changed from no format to `safe-text`
  - the `identifier` request property format changed from no format to `safe-text`
  - the `name` request property format changed from no format to `safe-text`

[Operation history](https://skmtc.dev/keycardai/apis/keycard-ai-keycard-api/changes/zones/:zoneId/providers/post.md)

---

[API](https://skmtc.dev/keycardai/apis/keycard-ai-keycard-api.md) - [All operations](https://skmtc.dev/keycardai/apis/keycard-ai-keycard-api/llms.txt) - [OpenAPI document](https://skmtc.dev/keycardai/apis/keycard-ai-keycard-api/revisions/0dee67e0a73a?raw)
