# Create a credential invitation.

Creates a pending invitation in the organization and environment selected by the authenticated service user and required headers.
The response contains the only current plaintext code. DeepCredentials does not email the code or return a redemption URL in the B2B flow. Your system owns code delivery and the recipient experience. Exchange the recipient's email and code through `POST /api/v1/public/credential-invitations/redeem`; where and how your system exposes that flow is up to you.
Only one pending invitation may exist for the same organization, environment, credential definition, and normalized email address. `reference_id` is correlation metadata only; it does not make this operation idempotent or unique.

Endpoint: POST /b2b/v1/credential-invitations
Version: 1.0.0
Security: BearerAuth

## Security:

  - `BearerAuth` (unknown)
    http bearer JWT

## Header parameters:

  - `X-Org-Id` (string, required)
    Organization the call is acting on. The authenticated service user must be a member of this organization in DeepAdmin; otherwise the request returns 404.

  - `X-Environment` (string, required)
    Environment the call is scoped to. Invitation resources are isolated per environment.

## Request fields (application/json):

  - `credential_definition_id` (string, required)
    Credential definition to issue after redemption. Configure it in the portal before making runtime B2B calls.

  - `email` (string, required)
    Recipient email used together with the code by the public redemption endpoint. It is trimmed and normalized to lowercase when stored. DeepCredentials does not email it in this B2B flow.

  - `claims` (object, required)
    Claim values for the eventual credential. Keys and JSON value types must match the credential definition, all mandatory claims must be present, and the serialized payload must not exceed 6 MB. Invitation responses do not return these values; retain them in your own durable request record when lost-response recovery matters.

  - `reference_id` (string)
    Optional correlation identifier from your system; echoed on the resource.

  - `invitation_ttl_seconds` (integer, required)
    Positive lifetime of the invitation code in seconds.

  - `offer_validity_seconds` (integer)
    Optional positive lifetime, in seconds, of the credential offer created after redemption.

  - `validity_seconds` (integer)
    Optional eventual credential lifetime in seconds. Omit to use the credential definition default. Allowed range is 60 seconds through 10 years. Mutually exclusive with `valid_until`. Invitation responses do not return this value; retain it in your own durable request record when lost-response recovery matters.

  - `valid_until` (string)
    Optional credential lifetime as an absolute calendar day (YYYY-MM-DD). The credential expires at 23:59:59 of that day in the issuer's time zone (Europe/Zurich), whenever the invitation is redeemed. Mutually exclusive with `validity_seconds`. Not returned by invitation responses.

## Response 200:

  - `200` (unknown)
    Invitation created. The caller owns delivery of the returned code.

## Response 200 fields (application/json):

  - `invitation_id` (string, required)
    Credential invitation ID.

  - `environment` (string, required)
    Environment selected by `X-Environment` when the invitation was created.
    Enum: "beta", "production"

  - `credential_definition_id` (string, required)
    Credential definition used for the eventual offer.

  - `credential_definition_name` (string, required)
    Credential definition name captured when the invitation was created.

  - `email` (string, required)
    Normalized recipient email required for public redemption.

  - `code_last4` (string, required)
    Last four normalized code characters for support and delivery confirmation. This is not a redeemable code.

  - `status` (string, required)
    Current invitation lifecycle state.
    Enum: "pending", "redeemed", "expired", "revoked"

  - `reference_id` (string)
    Optional correlation identifier from your system; echoed on the resource.

  - `offer_validity_seconds` (integer)
    Configured lifetime of the offer created after redemption, when supplied at creation.

  - `redeemed_offer_id` (string)
    Offer created by a successful redemption. Present only after redemption.

  - `expires_at` (string, required)
    Invitation-code expiry timestamp in RFC 3339 UTC.

  - `redeemed_at` (string)
    Successful redemption timestamp in RFC 3339 UTC.

  - `revoked_at` (string)
    Revocation timestamp in RFC 3339 UTC.

  - `created_at` (string, required)
    Creation timestamp in RFC 3339 UTC.

  - `archived_at` (string)
    When an operator put this invitation away in the portal's archive, if they did. A filing decision in the portal's lists; nothing about the invitation changes with it, and it is absent while the invitation is not archived.

  - `code` (string, required)
    One-time plaintext invitation code. Returned only by create and rotate; the caller owns secure delivery.

## Response 400:

  - `400` (unknown)
    Request validation failed (`invalid_argument`), including malformed required headers, identifiers, filters, email, claims, or lifetime values.

## Response 400 fields (application/json):

  - `code` (string, required)
    Machine-readable error code.

  - `message` (string, required)
    Human-readable error description.

  - `details` (object)
    Optional structured data with additional context.

## Response 401:

  - `401` (unknown)
    The Bearer token is missing, invalid, or expired (`unauthenticated`).

## Response 401 fields (application/json):

  - `code` (string, required)
    Machine-readable error code.

  - `message` (string, required)
    Human-readable error description.

  - `details` (object)
    Optional structured data with additional context.

## Response 403:

  - `403` (unknown)
    The authenticated caller is not authorized for this operation (`permission_denied`). The `deepcredentials.issue` scope guard is wired but currently disabled as described above; this response may still come from another authorization gate.

## Response 403 fields (application/json):

  - `code` (string, required)
    Machine-readable error code.

  - `message` (string, required)
    Human-readable error description.

  - `details` (object)
    Optional structured data with additional context.

## Response 409:

  - `409` (unknown)
    A pending invitation already exists for this recipient and credential definition in the selected environment (`already_exists`).

## Response 409 fields (application/json):

  - `code` (string, required)
    Machine-readable error code.

  - `message` (string, required)
    Human-readable error description.

  - `details` (object)
    Optional structured data with additional context.

## Response 500:

  - `500` (unknown)
    Unexpected server failure (`internal`).

## Response 500 fields (application/json):

  - `code` (string, required)
    Machine-readable error code.

  - `message` (string, required)
    Human-readable error description.

  - `details` (object)
    Optional structured data with additional context.

