Public API: Allowed Origins

The allowed-origins list is the set of hosts allowed to load the project's snippet and mount the visual editor. Each entry is a bare host such as www.example.com or staging.example.com:3000: no https://, no path, and no trailing slash. An empty list means no host restriction is enforced. A project can hold up to 20 hosts.

This is one setting per project, not a collection of separate records, so there is nothing to paginate. The two endpoints below read the whole list and replace it in full.

All allowed-origins endpoints live under a project and authenticate with a Bearer token: a service token or a personal access token. Either way, your token names its own organization, so the path below carries only {projectId}, never {orgId}.

Plain text
https://app.avsb.cloud/api/v1/projects/{projectId}/allowed-origins
Plain text1 line

Scopes

A scope is a named permission on your token. It decides exactly what that token is allowed to read or change, so a token built for this endpoint only needs the two scopes below, not every scope AvsB offers.

OperationScope
Get the listprojects:read
Replace the listprojects:write

Every /api/v1 token is also rate-limited: a scoped token gets 600 reads and 120 writes per minute, and an admin:* token gets 600 requests per minute, reads and writes together. See Conventions for the response headers that show your remaining budget.

Get the allowed-origins list

GET /api/v1/projects/{projectId}/allowed-origins returns the project's current list. Requires projects:read.

curl https://app.avsb.cloud/api/v1/projects/<projectId>/allowed-origins \  -H "Authorization: Bearer avsb_svc_..."
Shell2 lines
Response
{  "data": {    "allowedOrigins": [      "www.example.com",      "shop.example.com"    ]  }}
JSON8 lines

A project outside your token's organization, or a project id that does not exist, returns 404:

Error response
{  "error": {    "code": "not_found",    "message": "Project not found",    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#not-found-errors",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON8 lines

Replace the allowed-origins list

PUT /api/v1/projects/{projectId}/allowed-origins replaces the entire list with the array you send. Requires projects:write. This is not a partial update: send the full list you want every time, including any hosts you are keeping.

The smallest request that works

The body has one required field, allowedOrigins. Send an empty array to remove every host restriction.

curl https://app.avsb.cloud/api/v1/projects/<projectId>/allowed-origins \  -X PUT \  -H "Authorization: Bearer avsb_svc_..." \  -H "Content-Type: application/json" \  -d '{ "allowedOrigins": ["www.example.com"] }'
Shell5 lines

Retrying a write safely

A PUT you send twice with the same body already leaves the project unchanged, because it replaces the whole list both times. If your network drops the response and you cannot tell whether the first attempt landed, add an Idempotency-Key header: replaying the same key with the same body returns the first response again, without writing twice.

curl https://app.avsb.cloud/api/v1/projects/<projectId>/allowed-origins \  -X PUT \  -H "Authorization: Bearer avsb_svc_..." \  -H "Content-Type: application/json" \  -H "Idempotency-Key: $(uuidgen)" \  -d '{    "allowedOrigins": [      "www.example.com",      "shop.example.com"    ]  }'
Shell11 lines
Response
{  "data": {    "allowedOrigins": [      "www.example.com",      "shop.example.com"    ]  }}
JSON8 lines

When a request is rejected

An entry with a scheme, a path, or any other character outside a-z0-9.- and an optional :port fails validation and returns 400 validation_failed:

400: a host is malformed
{  "error": {    "code": "validation_failed",    "message": "Request body failed validation",    "details": {      "issues": [        {          "param": "allowedOrigins.0",          "path": ["allowedOrigins", 0],          "code": "invalid_string",          "message": "Use a host like `staging.example.com`, optionally with `:port`. No scheme, no path."        }      ]    },    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#validation-errors",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON18 lines

Reusing an Idempotency-Key with a different body, instead of retrying the same one, is refused rather than silently applied:

409: idempotency key reused with a different body
{  "error": {    "code": "idempotency_conflict",    "message": "Idempotency-Key reused with a different request body",    "details": { "previousStatus": 200 },    "docUrl": "https://docs.avsb.cloud/docs/developer-reference/public-api/conventions#idempotency-key",    "requestId": "req_9f2c41ab7e0b4d1e8c35a6f0d2b91e77"  }}
JSON9 lines
Info

Each entry must be a bare host, optionally with a port: www.example.com or staging.example.com:3000. No scheme (https://) and no path. Each host can appear once: a list that names the same host twice is refused with 400, and the issue points at the repeat.

Next steps

Was this helpful?