The Avvail Guest Book API uses OAuth 2.0 with the Client Credentials flow to secure access. This approach is ideal for server-to-server communications, where your application requests an access token using a Client ID and Client Secret.
Overview
- Obtain Your Credentials — request a Client ID and Client Secret from our support team. Typically, you'll receive sandbox credentials first, then production credentials when you're ready.
- Request an Access Token — send a
POSTrequest to the relevant token URL. - Use the Access Token — include the token in the
Authorizationheader when calling the API.
Client Credentials
When integrating with the Guest Book API, you will be provided with:
- Client ID: A unique identifier for your application. This value is public and is used to identify your application during the OAuth flow.
- Client Secret: A confidential value that must be kept secure. This secret is used in conjunction with your Client ID when obtaining an access token.
Important: Always store your Client Secret in a secure, encrypted location, and never log it in plaintext.
Access Tokens
Requesting Tokens
Tokens are granted via the OAuth 2.0 Client Credentials flow. Send a POST request to the relevant token URL:
- Sandbox:
https://sandbox.auth.avvail.com/oauth/token - Production:
https://auth.avvail.com/oauth/token
Request Example
curl -X POST https://auth.avvail.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "https://api.avvail.com/",
"grant_type": "client_credentials"
}'
Response Example
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"scope": "reservations:read",
"expires_in": 86400,
"token_type": "Bearer"
}
Verifying Tokens
Each access token is a JWT (JSON Web Token) containing standard OAuth 2.0 claims. A decoded token looks like:
{
"iss": "https://auth.avvail.com/",
"sub": "xRt7hZmGvA9KsL2Dy5EbXfJ8iNqW3uP6@clients",
"aud": "https://api.avvail.com/",
"iat": 1677721600,
"exp": 1677807600,
"scope": "reservations:read venues:read availability:read",
"gty": "client-credentials",
"azp": "xRt7hZmGvA9KsL2Dy5EbXfJ8iNqW3uP6",
"org_id": "org_7f3c2b1a8e4d4f9c"
}
Verify the token's signature using the JSON Web Key Set (JWKS) at https://auth.avvail.com/.well-known/jwks.json. Use a standard JWT library to perform RS256 signature validation.
Token Claims
| Claim | Description |
|---|---|
azp |
Authorized party — your Client ID. Identifies the API caller. |
scope |
Space-delimited list of granted scopes. Authorizes which endpoints can be called. |
org_id |
Organization id. When present, identifies the entity (brand or distribution channel) the token was issued for. The server uses this to resolve entity context automatically. |
aud |
Audience. Must equal https://api.avvail.com/. |
exp |
Expiration timestamp (seconds since epoch). |
Using Tokens
Include the token in the Authorization header for every API request:
Authorization: Bearer <ACCESS_TOKEN>
Refreshing Tokens
Tokens are not refreshable via a refresh token. Request a new token using the same Client ID and Client Secret before the current token expires. If your application runs continuously, schedule a refresh before expiration to avoid interrupted service.
Token Expiration
By default, tokens expire 24 hours after issuance. If you need a shorter token duration, contact our support team to adjust the default settings.
Entity Context
Every v2 request is scoped to a single entity (brand or distribution channel). The server resolves the entity for each request automatically, in this order:
- JWT
org_idclaim (recommended) — when your access token is bound to an organization, the corresponding entity is used. Entity context is bound to the token and cannot be tampered with at the request layer. See Requesting an Organization-Bound Token below. X-Entity-Idrequest header (deprecated) — used when the token has noorg_idclaim. Pass the entity's UUID:X-Entity-Id: 7f3c2b1a-8e4d-4f9c-a6b2-3d5e1a7c9f2bWhen the token carries an
org_id, the header is ignored; the token-bound entity always wins. The header is deprecated and will eventually be retired in favor of token-bound entity context viaorg_id. No sunset date has been set; existing integrations continue to work and will receive adequate notice before any removal. New integrations should use organization-bound tokens from the start.Default entity — if neither
org_idnorX-Entity-Idis present, the entity configured as your credential's default is used.
Your credentials may be linked to one or more entities. Requests targeting an entity that is not assigned to your credentials are rejected with 403 Forbidden. If the resolved entity does not exist, the response is 404 Not Found.
Requesting an Organization-Bound Token
Your credentials are pre-configured to issue organization-bound tokens for each entity assigned to them — no setup is required on your side.
Include the
organizationparameter when requesting a token. Pass theorg_idof the entity you want to target:curl -X POST https://auth.avvail.com/oauth/token \ -H "Content-Type: application/json" \ -d '{ "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "audience": "https://api.avvail.com/", "grant_type": "client_credentials", "organization": "org_7f3c2b1a8e4d4f9c" }'The returned access token carries an
org_idJWT claim matching the entity. To discover theorg_idvalues for your entities, see Discoveringorg_idvalues below.Use the token. Include it in the
Authorizationheader for every API request. The server resolves entity context from the token'sorg_idclaim; anyX-Entity-Idvalue in the request is silently ignored.
Existing integrations that authenticate without the organization parameter and pass X-Entity-Id continue to work unchanged. See the API v2 Migration Guide for the upgrade narrative.
Discovering org_id values
Each entity exposed via GET /v2/entities carries an org_id field — the organization identifier you pass as the organization parameter in token requests to target that entity. Call the endpoint with any valid token (the response is scoped to the entities your credentials are authorized for) and read the org_id from each entry:
curl https://api.avvail.com/v2/entities \
-H "Authorization: Bearer <ACCESS_TOKEN>"
{
"data": [
{
"id": "7f3c2b1a-8e4d-4f9c-a6b2-3d5e1a7c9f2b",
"name": "Acme Hotels Production",
"org_id": "org_7f3c2b1a8e4d4f9c",
"...": "..."
}
],
"pagination": { "...": "..." }
}
For entities whose organization has not yet been provisioned, org_id is null. In that case, omit the organization parameter when requesting a token — the token will fall back to your identity's default entity for the request's context.
Identity Introspection
For self-introspection (your identity's effective status, default entity, associated entity IDs, and the IDs of any delegated identities you manage), call GET /v2/identities/me:
curl https://api.avvail.com/v2/identities/me \
-H "Authorization: Bearer <ACCESS_TOKEN>"
The endpoint requires a valid access token but no specific OAuth scope — introspection is a baseline capability. The response is wrapped in the standard v2 {data: ...} envelope and is polymorphic by type:
{
"data": {
"id": "8d2e1c4b-9a7f-4e3d-b5c8-1f6a3d9c2e7b",
"type": "partner",
"name": "Acme Hotels Production",
"client_id": "xRt7hZmGvA9KsL2Dy5EbXfJ8iNqW3uP6",
"status": "active",
"default_entity_id": "7f3c2b1a-8e4d-4f9c-a6b2-3d5e1a7c9f2b",
"associated_entity_ids": ["7f3c2b1a-..."],
"delegated_identity_ids": ["1e3d5c7b-..."],
"created_at": "2025-08-12T14:23:01Z",
"updated_at": "2026-04-30T09:11:45Z"
}
}
A delegated identity sees parent_identity_id (the partner that owns it) instead of delegated_identity_ids. Suspended identities still receive a 200 OK with status: "suspended", plus suspension_source ("self" or "parent") and suspended_at populated — the endpoint is designed to help you diagnose your own state when other endpoints are returning 403 Forbidden for suspension reasons.
associated_entity_ids lists only currently active entities. Resolve each ID to a full record (including org_id) via GET /v2/entities.
The me path convention
Where :id would normally appear in an identity-scoped path (for example /v2/identities/:id/…), pass the literal string me to refer to the caller's own identity. The server resolves me to the identity carried by your JWT. This convention is reserved for identity-scoped paths in this API.
Delegate listing (GET /v2/identities/me/delegates)
If you are a partner identity, GET /v2/identities/me/delegates returns the full record for each delegate you manage, paginated using the standard ?page= / ?limit= query parameters. The response uses the v2 list envelope:
{
"data": [
{
"id": "1e3d5c7b-...",
"type": "delegate",
"name": "Acme Boutique Boston",
"parent_identity_id": "8d2e1c4b-...",
"...": "..."
}
],
"pagination": { "current_page": 1, "total_pages": 1, "total_items": 1, "items_per_page": 20 }
}
Delegated identities calling GET /v2/identities/me/delegates receive {"data": [], "pagination": {...}} with HTTP 200 — delegates cannot themselves have delegates. This is intentional, not an error.
To fetch a single delegate by ID, call GET /v2/identities/me/delegates/:id. Reading a delegate that does not belong to the calling partner returns 404 Not Found rather than 403 Forbidden, so the endpoint cannot be used as an existence oracle for arbitrary delegate IDs.
Scopes
API credentials are issued with specific scopes that determine which endpoints are accessible. The v2 API supports the following scopes:
| Scope | Description |
|---|---|
availability:read |
Query real-time availability options |
commitments:read |
Read your commitments |
commitments:update |
Update your commitments |
entities:create |
Create entities |
entities:read |
Read entity data |
entities:update |
Update entities |
entities:upload_logo |
Upload entity logos |
holds:create |
Create temporary capacity holds |
holds:delete |
Release capacity holds early |
markets:read |
List geographic markets for multi-venue search |
reservations:create |
Create reservations |
reservations:read |
Read reservation data |
reservations:update |
Modify existing reservations |
reservations:cancel |
Cancel reservations |
venues:read |
Read venue data |
To adjust the scopes assigned to your credentials, email support@avvail.com.
Security Best Practices
- Use Secure Storage: Store the Client Secret and access tokens in a secure, encrypted location (e.g., environment variables or a secrets manager). Do not commit them to source control or include them directly in application code.
- Never Log Secrets or Tokens in Plaintext: Avoid printing the Client Secret or access tokens to logs. If logging is necessary for debugging, redact or mask the critical parts (e.g., only log the first 4 and last 4 characters).
- Verify and Monitor: Verify all access tokens and monitor API usage to detect suspicious activity. If you suspect credentials have been leaked, rotate them immediately.