# issuePartnerToken

Source: /openapi/thomas-federated.openapi.json

## Operation

| Method | URL |
|---|---|
| POST | https://staging-api.thomas.co/oauth/token |

| Field | Value |
|---|---|
| operationId | issuePartnerToken |
| method | POST |
| server | https://staging-api.thomas.co/v1 |
| path | /oauth/token |
| tags | `Partner Auth` |
| summary | Exchange partner client credentials for a Platform token |
| badges | None |

## Request Parameters

None.

## Request Body

None.

## Responses

| Status | Description | Schema refs |
|---|---|---|
| 200 | The RFC 6749 §5.1 envelope: `access_token`, `token_type: Bearer`, `expires_in: 600`. No refresh token. Served under `Cache-Control: no-store`. |  |
| 400 | `invalid_request` (missing or malformed parameters) or `unsupported_grant_type`. |  |
| 401 | `invalid_client` — wrong identifier, wrong secret, unknown client, or a credential that is revoked or past its effective expiry. Byte-identical across all of them by design. |  |
| 429 | `slow_down` — the pre-Keycloak abuse boundary refused this attempt. Applies to failed attempts as well as successful ones, and is counted against both the per-client and per-source ceilings. |  |
| 503 | `temporarily_unavailable` — the credential provider could not be reached. Fails closed; never falls back to a cached or local credential check. |  |

### Response 429 headers

| Name | Description | Schema |
|---|---|---|
| Retry-After | Seconds until the rate-limit block expires before retrying. | {"type":"integer","minimum":0} |
| RateLimit-Limit | Configured request limit for the active rate-limit window. | {"type":"integer"} |
| RateLimit-Remaining | Requests remaining in the active rate-limit window; zero when blocked. | {"type":"integer"} |
| RateLimit-Reset | Seconds until the rate-limit block expires. | {"type":"integer","minimum":0} |

## Artifact Examples

### Response 429 example

```json
{
  "error": "slow_down"
}
```
