# Ticket

`POST /api/auth/ticket`

Exchanges an appKey/appSecret pair for an authentication token (a
"ticket", in JWT form) that must accompany every subsequent API request.

**Expiry model**

- Expiry is ABSOLUTE and fixed at issuance. It is not extended by API
  activity, and no renewed ticket is ever returned on a subsequent call.
- TTL parameter: the ticket's total lifetime in seconds, counted from
  issuance. Defaults to 24 hours (86400) when not supplied.
- The response's `expiresAt` is the authoritative expiry instant (Unix
  seconds). Treat it as final for that ticket.
- The TTL you request IS the lifetime. It must be a positive number of
  seconds and may not exceed 365 days (31536000); larger values are
  rejected. That ceiling bounds what you may ask for — it is not an
  additional expiry running alongside the TTL.

**Usage guidelines**

- Cache the ticket and reuse it until `expiresAt`, then request a new
  one.
- Do NOT call this endpoint before every API call — it is expensive and
  unnecessary.
- Renew proactively, shortly before `expiresAt`. Because expiry is
  absolute, a busy integration will still expire on schedule.
- Send the ticket in the Authorization header as: "Bearer <ticket>".

**Error handling**

- 401: appKey/appSecret is invalid — contact your TTDbooking
  representative.
- 401: the ticket has reached `expiresAt` — call this endpoint again for
  a new one.
- 429: rate limit exceeded — wait before retrying.

## Request headers

| Header | Required | Description |
| --- | --- | --- |
| `Client-Request-Timestamp` | No | Client request time (when the client began sending the request), as a unix timestamp. |
| `IP` | No | Client IP address; accepts both IPv4 and IPv6. |
| `Language` | No | IETF BCP 47 language tag, e.g. "en" or "en-US". Defaults to "en-US". Source cites https://masonreview.com/posts/ietf-bcp-47-language-tags/ as the reference for the tag format. |
| `Request-Id` | No | Identifies this single request; values must not repeat. |
| `Trace-Id` | No | Correlates a group of related requests. |
| `Authorization` | No | Begins with "Bearer ". Obtained from the Ticket response. The Ticket endpoint itself does not require it. |

## Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `appKey` | string | Yes | The application key used to obtain this ticket. |
| `appSecret` | string | Yes | The application secret used to obtain this ticket. |
| `ttl` | integer | No | Total lifetime of this ticket, expressed as an integer number of seconds and counted from issuance. It is NOT an idle timeout: expiry is absolute and is not extended by API activity. When omitted the server applies a 24-hour (86400) default. Must be positive and no greater than 365 days (31536000). The source schema declares no `default`, `minimum` or `maximum`; those bounds are enforced by this implementation. |


### Example request

```json
{
  "appKey": "ttdbooking_api_demo",
  "appSecret": "ttdbooking_api_demo",
  "ttl": 3600
}
```

## Response

Successful calls return the standard envelope. `code` is `0` on success — check it rather than the HTTP status alone, because some business failures are delivered with HTTP 200.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | integer | No | Result code for the call. The source supplies no enumeration, success value or description for this field. |
| `msg` | string | No | Result message for the call. The source supplies no description or example for this field. |
| `data` | hotel.api.protocol.TicketResp | No |  |
|    `data.ticket` | string | Yes | The generated ticket value. |


## Failure responses

| HTTP | Meaning |
| --- | --- |
| 400 | Bad Request |
| 401 | Unauthorized. Either the appKey/appSecret pair is invalid (contact your TTDbooking representative) or the token has expired through inactivity — request a new ticket from this endpoint. |
| 403 | Forbidden |
| 429 | Too Many Requests — rate limit exceeded; wait before retrying. |

Every failure uses the `{ code, msg }` envelope. See [Error handling](../guides/error-handling) for the full business-code table.
