Exchange API key for access token

Exchanges a long-lived SignStack API key for a short-lived (1 hour) JWT access token.

Send the API key in the request body — this is the only endpoint in the API that does not require a Bearer token. Use the returned accessToken as Authorization: Bearer <accessToken> on every other request.

Request: Content-Type: application/json is required.

Response caching: the response carries Cache-Control: no-store (RFC 6749 §5.1) — never cache an access token at any intermediary. On the client side, hold the token in memory until close to expiresAt and refresh proactively; reactive refresh on 401 also works but adds latency to one request in N.

Where to get an API key: mint one in Studio (Settings → API Keys), or via POST /v1/orgs/{orgId}/namespaces/{namespaceKey}/api-keys.

Body·
required
application/json
  • apiKey
    Type: string
    required

    Your full API key in the form sk_ns_<mode>_<keyId>_<secret>.

  • grantType
    enum
    const:  
    api_key
    required

    Always api_key.

    values
    • api_key
Responses
  • application/json
  • application/json
  • application/json
Request Example for post/v1/auth/token
curl https://api.signstack.ai/v1/auth/token \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "grantType": "api_key",
  "apiKey": "sk_ns_test_8a1f3c4d5e6b7a8d9c0e1f2a3b4c5d6e_K2vR8mNqL3xY7wZ4hP9bF6jT5sV1aQ8cD7eW3rA0xZb"
}'
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresIn": 3600,
  "expiresAt": "2026-04-21T16:30:00.000Z",
  "scopes": [
    "resource:read",
    "resource:create",
    "resource:update",
    "workflow:read",
    "workflow:create",
    "workflow:execute"
  ],
  "subject": {
    "type": "service_account",
    "id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
    "orgId": "f1e2d3c4-b5a6-4789-a012-345678901234",
    "namespaceKey": "acme-test",
    "mode": "test"
  }
}