> ## Documentation Index
> Fetch the complete documentation index at: https://docs.guile.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange a native Apple credential

> Exchange a Sign in with Apple identity token issued to the native iOS app
for a Guile authentication session. The server verifies Apple's signature,
issuer, audience, and expiry before resolving the verified Apple identity
to its Guile user. Each identity token can be exchanged only once.

An invalid, expired, or incomplete Apple credential returns 401 without
issuing a session. Reusing a previously exchanged credential returns 409
without issuing another session.



## OpenAPI

````yaml /api-reference/Authentication/openapi.yaml post /auth/oauth/apple/callback
openapi: 3.0.0
info:
  title: Authentication
  version: 0.1.0
  contact:
    name: Guile Engineering
    url: https://www.guile.app
    email: engineering@guile.app
  license:
    name: MIT
    url: https://opensource.org/license/mit
  description: >-
    The Authentication API provides operations which create and verify

    authentication challenges for users. Upon verification, users are issued

    an access token to use for protected API operations. Additionally,

    users are issued an offline refresh token. The refresh token is used in

    exchange for a new access token without challenge verification. Access

    tokens are short lived, typically valid for only 15 minutes. Access and

    refresh tokens may be revoked if they are determined to have been
    compromised.
servers:
  - url: https://api.guile.app
    variables: {}
  - url: https://guile.fly.dev
    variables: {}
security: []
tags:
  - name: Passkeys
    description: Register and manage passkeys
  - name: Token management
    description: Issue, refresh, and revoke access tokens
  - name: Email verification
    description: Prove ownership of an email on an authenticated account
  - name: Registration
    description: Register a new customer account
  - name: Challenges
    description: Start and complete sign-in challenges
paths:
  /auth/oauth/apple/callback:
    post:
      tags:
        - Token management
      summary: Exchange a native Apple credential
      description: >-
        Exchange a Sign in with Apple identity token issued to the native iOS
        app

        for a Guile authentication session. The server verifies Apple's
        signature,

        issuer, audience, and expiry before resolving the verified Apple
        identity

        to its Guile user. Each identity token can be exchanged only once.


        An invalid, expired, or incomplete Apple credential returns 401 without

        issuing a session. Reusing a previously exchanged credential returns 409

        without issuing another session.
      operationId: exchangeNativeAppleCredential
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/nativeAppleSignInRequest'
            example:
              idToken: eyJraWQiOiJhcHBsZS1rZXkifQ.example
      responses:
        '200':
          description: |-
            Ok.
            The operation succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/authTokens'
              example:
                authToken: eyJhbGciOiJIUzI1NiJ9.example
                refreshToken: eyJhbGciOiJIUzI1NiJ9.refresh
        '400':
          description: >-
            Bad Request.

            The request body, request headers, and/or query parameters are not
            well-formed.



            This problem response may have one of the following `type` values:

            *
            [https://docs.guile.app/problems/badRequest](https://docs.guile.app/problems/badRequest)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/apiProblem'
        '401':
          description: >-
            Unauthorized.

            The operation requires authentication but no authentication or
            insufficient authentication was given.



            This problem response may have one of the following `type` values:

            *
            [https://docs.guile.app/problems/unauthorized](https://docs.guile.app/problems/unauthorized)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/apiProblem'
        '409':
          description: >-
            Conflict.

            The request conflicts with the state of the application.



            This problem response may have one of the following `type` values:

            *
            [https://docs.guile.app/problems/conflict](https://docs.guile.app/problems/conflict)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/apiProblem'
components:
  schemas:
    nativeAppleSignInRequest:
      type: object
      required:
        - idToken
      properties:
        idToken:
          type: string
          minLength: 1
          maxLength: 16384
          description: The signed Apple identity token returned by AuthenticationServices.
        user:
          type: string
          maxLength: 4096
          description: >-
            Apple's first-authorization user JSON, when AuthenticationServices
            supplies it.
        nonce:
          type: string
          minLength: 16
          maxLength: 256
          description: >-
            The raw nonce the client gave Apple for this sign-in, sent so the
            token

            can be bound to this attempt. Required whenever the identity token

            carries a nonce claim.
      description: >-
        The native Sign in with Apple credential to exchange for a Guile
        session.
    authTokens:
      type: object
      required:
        - authToken
        - refreshToken
      properties:
        authToken:
          allOf:
            - $ref: '#/components/schemas/issuedToken'
          description: A bearer token representing an authenticated user.
        refreshToken:
          allOf:
            - $ref: '#/components/schemas/issuedToken'
          description: |-
            An offline refresh token. Refresh tokens are exchanged
            for a new authentication token without going through
            a challenge workflow.
      description: |-
        The JSON representation of issued authentication tokens as
        the result of a successful authentication challenge or the
        exchange of a refresh token.
    apiProblem:
      type: object
      required:
        - type
        - title
        - occurredAt
        - id
        - status
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/uri'
          description: A URI reference that identifies the problem type.
        title:
          type: string
          maxLength: 120
          description: >-
            A short, human-readable summary of the problem type. The title is
            usually the same for all

            problems with the same `type`.
        occurredAt:
          type: string
          format: date-time
          description: >-
            The date-time when this problem occurred, in [RFC
            3339](https://tools.ietf.org/html/rfc3339)

            date-time `YYYY-MM-DDThh:mm:ss.sssZ` format, UTC. This is derived
            and immutable.
        detail:
          type: string
          maxLength: 256
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
        id:
          allOf:
            - $ref: '#/components/schemas/resourceId'
          description: >-
            The unique identifier for this problem. This is an immutable opaque
            string.
        status:
          allOf:
            - $ref: '#/components/schemas/statusCode'
          description: >-
            The [HTTP status
            code](https://datatracker.ietf.org/doc/html/rfc7231#section-6)for
            this

            occurrence of the problem.
        instance:
          allOf:
            - $ref: '#/components/schemas/uri'
          maxLength: 2048
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem. This is the URI of an

            API resource that the problem is related to, with a unique error
            correlation ID URI fragment.
        attributes:
          type: object
          additionalProperties: {}
          description: >-
            Additional optional attributes related to the problem. This data
            conforms to the schema

            associated with the error type.
        recovery:
          allOf:
            - $ref: '#/components/schemas/clientFailureRecovery'
          description: The recovery contract for this problem occurrence.
        problems:
          type: array
          items:
            $ref: '#/components/schemas/problem'
          maxItems: 128
          description: |-
            Optional root-causes if there are multiple problems in the request
            or API call processing.
      description: >-
        API problem or error response, as per

        [RFC 9457
        application/problem+json](https://tools.ietf.org/html/rfc9457).
    issuedToken:
      type: string
      format: jwt
      description: |-
        A token that has been issued by an authorization server, as
        defined by [RFC7519](https://datatracker.ietf.org/doc/html/rfc7519).
    uri:
      type: string
      maxLength: 1024
      format: uri
      description: A URI reference to an internal or external resource.
    resourceId:
      type: string
      description: >-
        The unique, opaque system identifier for a resource.

        This case-sensitive ID is also used as path parameters in URLs or in
        other

        properties or parameters that reference a resource by ID rather than
        URL.
    statusCode:
      type: integer
      format: uint16
      minimum: 100
      maximum: 599
      description: The HTTP status code for a response.
    clientFailureRecovery:
      type: object
      required:
        - outcome
        - retry
      properties:
        outcome:
          allOf:
            - $ref: '#/components/schemas/clientFailureOutcome'
          description: The known outcome of the request.
        retry:
          allOf:
            - $ref: '#/components/schemas/clientRetryDirective'
          description: The safe retry action for the request.
        sessionAction:
          allOf:
            - $ref: '#/components/schemas/clientSessionAction'
          description: The session action required before the request can continue.
        rateLimit:
          allOf:
            - $ref: '#/components/schemas/rateLimit'
          description: The rate limit state that prevented the request.
      description: The recovery contract for a failed client request.
    problem:
      type: object
      required:
        - type
        - title
        - occurredAt
        - id
        - status
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/uri'
          description: A URI reference that identifies the problem type.
        title:
          type: string
          maxLength: 120
          description: >-
            A short, human-readable summary of the problem type. The title is
            usually the same for all

            problems with the same `type`.
        occurredAt:
          type: string
          format: date-time
          description: >-
            The date-time when this problem occurred, in [RFC
            3339](https://tools.ietf.org/html/rfc3339)

            date-time `YYYY-MM-DDThh:mm:ss.sssZ` format, UTC. This is derived
            and immutable.
        detail:
          type: string
          maxLength: 256
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
        id:
          allOf:
            - $ref: '#/components/schemas/resourceId'
          description: >-
            The unique identifier for this problem. This is an immutable opaque
            string.
        status:
          allOf:
            - $ref: '#/components/schemas/statusCode'
          description: >-
            The [HTTP status
            code](https://datatracker.ietf.org/doc/html/rfc7231#section-6)for
            this

            occurrence of the problem.
        instance:
          allOf:
            - $ref: '#/components/schemas/uri'
          maxLength: 2048
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem. This is the URI of an

            API resource that the problem is related to, with a unique error
            correlation ID URI fragment.
        attributes:
          type: object
          additionalProperties: {}
          description: >-
            Additional optional attributes related to the problem. This data
            conforms to the schema

            associated with the error type.
      description: >-
        Standard problem or error response, as per

        [RFC 9457
        application/problem+json](https://tools.ietf.org/html/rfc9457).
    clientFailureOutcome:
      type: string
      enum:
        - notApplied
        - unknown
      description: The known outcome of a failed client request.
    clientRetryDirective:
      type: string
      enum:
        - doNotRetry
        - retrySameRequest
        - retrySameRequestAfterDelay
      description: The safe retry action for a failed client request.
    clientSessionAction:
      type: string
      enum:
        - refresh
        - signIn
      description: The session action required before a failed request can continue.
    rateLimit:
      type: object
      required:
        - limit
        - remaining
        - resetsAt
      properties:
        limit:
          type: integer
          format: uint64
          description: The maximum number of requests allowed in the active window.
        remaining:
          type: integer
          format: uint64
          description: The number of requests remaining in the active window.
        resetsAt:
          type: string
          format: date-time
          description: >-
            The date-time when the active window resets, in [RFC
            3339](https://tools.ietf.org/html/rfc3339) date-time
            `YYYY-MM-DDThh:mm:ss.sssZ` format, UTC.
      description: The rate limit state for the request.

````