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

# Short-lived tokens

> Exchange an API key for a scoped, time-limited token.

## Exchange an API key for a JWT

Use `POST /api/v1/authentication/api-keys/exchange-token` when you need a short-lived JWT for a downstream service.
Send your MKA1 API key in `Authorization`.
Then pass a JSON body with:

* `audience`: The service URL that should accept the token.
* `externalUserId`: Your end user ID for the JWT subject.
* `expiresIn`: Optional token lifetime in seconds. The OpenAPI spec allows 300 to 2592000.
* `permissions`: Optional subset of the key's scopes (its permissions, for example `read:responses` or `read:files`) to embed in the token. If omitted, the token carries every scope the key has. A token can narrow the key's scopes but never widen them.

<CodeGroup>
  ```ts TypeScript SDK theme={null}
  import { SDK } from '@meetkai/mka1';

  const sdk = new SDK({ bearerAuth: 'Bearer <mka1-api-key>' });

  const result = await sdk.auth.apiKeys.exchangeToken({
    requestBody: {
      audience: 'https://my-awesome-website.com',
      externalUserId: 'user_123',
      expiresIn: 3600,
      // permissions: ['read:responses', 'read:files'],
    },
  })
  ```

  ```python Python SDK theme={null}
  from meetkai_mka1 import SDK

  sdk = SDK(bearer_auth="Bearer <mka1-api-key>")

  jwt = sdk.auth.api_keys.exchange_token(
      audience="https://my-awesome-website.com",
      external_user_id="user_123",
      expires_in=3600,
      # permissions=["read:responses", "read:files"],
  )

  # Use the JWT for subsequent requests
  authed = SDK(bearer_auth=f"Bearer {jwt.token}")
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Requests;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer <mka1-api-key>");

  var result = await sdk.Auth.ApiKeys.ExchangeTokenAsync(
      body: new ExchangeApiKeyTokenRequestBody()
      {
          Audience = "https://my-awesome-website.com",
          ExternalUserId = "user_123",
          ExpiresIn = 3600,
          // Permissions = new List<string>() { "read:responses", "read:files" },
      });

  Console.WriteLine(result.Object!.Token);
  ```

  ```bash CLI theme={null}
  mka1 auth api-keys exchange-token \
    --audience https://my-awesome-website.com \
    --external-user-id user_123 \
    --expires-in 3600
  ```

  ```bash Bash theme={null}
  curl https://apigw.mka1.com/api/v1/authentication/api-keys/exchange-token \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --data '{
      "audience": "https://my-awesome-website.com",
      "externalUserId": "user_123",
      "expiresIn": 3600
    }'
  ```
</CodeGroup>

A successful response returns a JSON object with `token`.

## Use a JWT for subsequent requests

Once you have a JWT from the exchange endpoint, use it as a bearer token in place of your API key.
This lets you issue short-lived credentials to downstream services or end users without exposing your API key.

<CodeGroup>
  ```ts TypeScript SDK theme={null}
  // Use the JWT returned from the exchange endpoint
  const jwtSdk = new SDK({ bearerAuth: `Bearer ${result.token}` })

  const response = await jwtSdk.llm.responses.create({
    responsesCreateRequest: {
      model: 'auto',
      input: 'Write a short welcome message.',
    },
  })
  ```

  ```python Python SDK theme={null}
  # Use the JWT returned from the exchange endpoint
  authed = SDK(bearer_auth=f"Bearer {jwt.token}")

  res = authed.llm.responses.create(
      model="auto",
      input="Write a short welcome message.",
  )
  ```

  ```csharp C# SDK theme={null}
  // Use the JWT returned from the exchange endpoint
  var jwtSdk = new SDK(bearerAuth: $"Bearer {result.Object!.Token}",
      serverUrl: "https://apigw.mka1.com");

  var res = await jwtSdk.Llm.Responses.CreateAsync(new ResponsesCreateRequest()
  {
      Model = "auto",
      Input = ResponsesCreateRequestInput.CreateStr("Write a short welcome message."),
  });
  ```

  ```bash CLI theme={null}
  # Pass the JWT explicitly via -H to override MKA1_BEARER_AUTH
  mka1 llm responses create \
    --model auto \
    --input '"Write a short welcome message."' \
    -H 'Authorization: Bearer <jwt-token>'
  ```

  ```bash Bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header "Authorization: Bearer <jwt-token>" \
    --data '{
      "model": "auto",
      "input": "Write a short welcome message."
    }'
  ```
</CodeGroup>

## Related guides

See [End-user identity](/docs/end-user-identity) for delegated requests and [Tenant isolation](/docs/authentication-deep-dive) for the validation path.
