# Authentication

Every call carries your credential as a Bearer token in the `Authorization` header.

```bash
curl -X POST "https://highstartravel.com/api/v1/transfer/getCatalog" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The credential is an opaque string that identifies your company. It is not a JWT and you cannot read anything from it. It does not expire on its own.

## Get a credential

Credentials are issued by Highstar Travel. Ask your account manager for a sandbox credential first and a production credential when your integration is ready. See [Support](/developers/guides/support).

## Send it only in the header

Do not send the credential in the body or in the query string. Query strings end up in proxy logs and browser history.

The older `id_company` field is still accepted on some endpoints of existing integrations, and it may stop being accepted. Do not use it in a new integration. Transfers and Disney reject it with `401`.

If you send both the header and `id_company`, the two values must be the same. If they differ, the API answers `403`:

```json
{
  "error": "Credential mismatch",
  "message": "The 'id_company' in the request does not match the Authorization bearer token.",
  "code": 403,
  "request_id": "3f8a9b2c4d5e6f7a8b9c0d1e2f3a4b5c"
}
```

## Authentication errors

| HTTP | `error` | Meaning | What to do |
|---|---|---|---|
| 401 | `Authentication required` | The header is missing, or the endpoint does not accept `id_company`. Transfers and Disney always answer this way without the header. | Send `Authorization: Bearer <credential>`. |
| 403 | `Credential mismatch` | The header and `id_company` carry different values. | Stop sending `id_company`. |
| 403 | `Access forbidden` | The credential does not exist, or your account does not have this product enabled. | Check the credential. Then ask your account manager to enable the product. |
| 403 | `IP not allowed` | Your credential is restricted to a list of IP addresses and the request came from another one. | Ask your account manager to register your outbound IP. |

Two details about the shape of these responses:

- Hotels and Transfers answer `Access forbidden` with the full error envelope. On Universal and Disney, the same `403` body has only a `message` field: `{"message": "Access forbidden: You do not have permission to perform this request."}`. Detect it by the HTTP status.
- Some products may answer a missing credential with `400` or `403` instead of `401`, depending on the endpoint. Treat any of the three as an authentication problem and check the header.

## Permissions

The credential is enabled per product: Transfers, Hotels, Universal and Disney. Each one is independent. You can have Universal without Disney. A call to a product you do not have returns `403`.

A credential can also be restricted to a list of IP addresses. If you want that, ask your account manager. A credential with no addresses registered accepts every IP.

## Keep the credential safe

- Store it in an environment variable or a secret manager.
- Call the API from your servers. Do not put the credential in browser code or in a mobile app.
- Do not commit it to a repository.
- If it leaks, tell your account manager right away and ask for a new one.

## Next

- [Conventions](/developers/guides/conventions) covers formats, rate limits and idempotency.
- [Errors](/developers/guides/errors) lists every error you can receive.
