Skip to main content
Provisioning flow
Language

Public REST API

Create or delete cside teams, manage domains, and add checkout-page selectors from your backend with the Enterprise REST API.

Use the cside Public REST API to create or delete teams, manage domains, and add checkout-page selectors from a backend workflow. The API uses JSON over HTTPS and an organization-level bearer token.

Interactive API reference

Use the interactive API reference to inspect the current request and response schemas. The OpenAPI document is available for code generation.

Base URL: https://api.cside.com

Provisioning flow

Team creation and domain registration are separate operations:

  1. Create an organization API token with the required permissions
  2. Call POST /v1/teams/ and save the returned teamId
  3. Call POST /v1/domains/ with that teamId and up to 100 hostnames
  4. Call POST /v1/payment-pages/ to add checkout-page selectors to the team
  5. Check every response before treating the provisioning run as complete

If domain registration fails, the team remains available. The API does not roll back a successful team creation.

Use List teams to check for an existing team before creating one.

Availability and authentication

Enterprise plan required

The Public API is available to organizations with an active Enterprise team. Contact sales if you need API access.

An organization administrator can generate a token from **Organization Settings

General** in the cside dashboard. Select Generate token, give the token a name (for example, the integration it belongs to), and choose only the permissions the integration needs:

PermissionAPI access
Create teams (teams:create)POST /v1/teams/
Delete teams (teams:delete)DELETE /v1/teams/
Register domains (domains:create)POST /v1/domains/
Delete domains (domains:delete)DELETE /v1/domains/
Add payment pages (payment_pages:create)POST /v1/payment-pages/
List teams (teams:read)GET /v1/teams/
List domains (domains:read)GET /v1/domains/

teams:create or teams:delete also permits a lookup with a non-empty name filter. domains:create or domains:delete permits a lookup with a non-empty domain filter. Unfiltered lists require teams:read or domains:read; read-only integrations can use these permissions without write access. Reads share the same 60-requests-per-minute organization budget as writes.

The dashboard shows each token once. Store it in a server-side secret manager before closing the dialog. Do not expose it in browser code, commit it to source control, or write it to application logs.

Tokens have the form cside_oatv2_<id>_<secret>. The <id> part identifies the token in the dashboard list and in audit logs; the rest is the secret.

Send the token with every request:

Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json

Manage and revoke tokens

Organization Settings > General lists every active token with its Name, masked Token prefix, Scopes, Created date, and Last used date. An organization can have up to 50 active tokens. When the limit is reached, revoke an unused token before generating a new one.

A token remains valid until it is revoked. You can revoke tokens in two ways:

  • Revoke a single token from the list. Only that token stops working, and other integrations keep running.
  • Revoke all tokens to invalidate every API token for the organization at once, including tokens that are not shown in the list.

Tokens generated before the token list existed are not shown in the list. They keep working, but Revoke all tokens is the only way to revoke them.

Token creation, single revocation, and Revoke all tokens are recorded in the organization audit log as org.api_token.create, org.api_token.revoke, and org.api_secret.rotate.

Keep IDs as strings

Send team_id and domain IDs as quoted decimal strings in JSON. Do not convert them to JavaScript numbers.

Rate limit

The API accepts 60 requests per organization per minute. This limit is shared across every endpoint, including the read endpoints, so a polling loop consumes the same budget your writes need. A request above the limit returns 429 with the rate_limited error code. Retry with backoff after the next minute begins.

Create a team

Use POST /v1/teams/ to create a team under the token’s organization.

curl --request POST \
  --url https://api.cside.com/v1/teams/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Acme Production"
  }'

The team name must:

  • Contain 3 to 32 characters
  • Use letters, numbers, underscores, spaces, or apostrophe characters
  • Be unique within the organization

Hyphens are not accepted in team names.

A successful request returns 201 Created:

{
  "data": {
    "teamId": "1897425263682514944"
  }
}

Save data.teamId. You need it to register or delete domains for the team.

A name conflict returns 409 team_name_exists with the existing team ID:

{
  "error": "team_name_exists",
  "message": "Team with name `Acme Production` already exists in this organization.",
  "data": {
    "teamId": "1897425263682514944"
  }
}
Create or fetch in one call

The endpoint does not accept an idempotency key. On 201 Created, save data.teamId. On 409 team_name_exists, read data.teamId to recover the existing team ID and continue domain registration. Check the specific error code before treating a conflict as an existing team.

Creating a team does not enable automatic domain onboarding. That capability is configured separately for each team and is disabled by default.

Register domains

Use POST /v1/domains/ to register 1 to 100 managed domain hostnames for a team. team_id is required when you use an organization API token.

curl --request POST \
  --url https://api.cside.com/v1/domains/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "team_id": "1897425263682514944",
    "domains": [
      "checkout.example.com",
      "app.example.com"
    ]
  }'

Send hostnames without a protocol, port, path, query string, or fragment. cside trims whitespace and normalizes accepted hostnames to lowercase.

Each item registers the exact hostname you send. The API does not create a wildcard domain, so include every hostname you need, such as both example.com and www.example.com.

The endpoint returns 200 OK with one result for each input, in the same order:

{
  "data": {
    "results": [
      {
        "status": "created",
        "input": "checkout.example.com",
        "domain": "checkout.example.com",
        "domainId": "1897425263682514945"
      },
      {
        "status": "existing",
        "input": "app.example.com",
        "domain": "app.example.com",
        "domainId": "1897425263682514946"
      },
      {
        "status": "invalid",
        "input": "not a hostname",
        "code": "invalid_domain",
        "message": "Domain is invalid."
      }
    ],
    "totals": {
      "created": 1,
      "existing": 1,
      "invalid": 1
    }
  }
}

The request can contain both successful and invalid results while still returning 200 OK. Inspect every result:

StatusMeaning
createdcside registered the hostname and returned its new domainId
existingThe same team already owns the hostname; the original domainId is returned
invalidcside did not register the hostname; inspect code and message

Retries are safe for domains that were already created for the same team. They return existing instead of creating a duplicate. A hostname managed by another team returns invalid with domain_already_licensed.

If the domains were saved but cside could not finish pushing the configuration to the delivery network, the request returns 503 domain_registration_unavailable with the message “Domains saved, but synchronization is incomplete. Retry to synchronize them.” Send the same request again: the saved hostnames come back as existing and the synchronization is retried.

New domains enter managed protection automatically. No separate activation API call is required. Configuration may take a short time to reach the delivery network.

Domain validation codes

An invalid result can include one of these codes:

CodeMeaning
empty_domainThe input is empty
invalid_domainThe hostname is not valid
public_suffix_domainThe input is a public suffix rather than a registrable hostname
internal_domainThe hostname is reserved or not allowed
reserved_ipDNS resolves the hostname to a reserved IP address
wildcard_conflictAn existing wildcard domain already covers this hostname
subdomain_conflictAn existing domain configuration already includes this subdomain
domain_already_licensedAnother team already manages the hostname
internal_errorcside could not validate or create the domain

Add payment pages

Use POST /v1/payment-pages/ to add one checkout-page selector to an existing team. team_id is required when you use an organization API token. It is optional for a team-scoped token, and if supplied it must match the token’s team.

curl --request POST \
  --url https://api.cside.com/v1/payment-pages/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "team_id": "1897425263682514944",
    "payment_page": "checkout.example.com/checkout"
  }'

Send payment_page as a canonical host/path selector without https://, a port, or a full URL. For example, use checkout.example.com/checkout, not https://checkout.example.com/checkout. cside trims surrounding whitespace and removes query strings and trailing slashes before storing the selector. A # fragment is kept as sent, so single-page apps that route their payment page by fragment can match on it. A selector that contains whitespace, such as checkout.example.com/check out, is rejected with 400 invalid_payment_page.

The selector uses the same pattern format as the dashboard. A team can have up to 500 checkout-page selectors. The endpoint does not register a domain, so register the hostname first with POST /v1/domains/ when it is not already managed by the team.

The endpoint returns 200 OK:

{
  "data": {
    "status": "created",
    "teamId": "1897425263682514944",
    "paymentPage": "checkout.example.com/checkout"
  }
}

Adding the same selector again is safe and returns status: "existing". A new selector returns status: "created". When the team owns matching domains, cside updates their checkout-page projections and related configuration after the team-level selector is stored.

Load cside for the team

Use the teamId returned by team creation in the standard cside script URL. Do not substitute a domainId.

<script
  src="https://[your-team-id].csidetm.com/client.js"
  referrerpolicy="origin">
</script>

The page hostname must be registered under the same team ID used in the script URL. A missing registration or team mismatch returns 403. If this happens immediately after registration, retry shortly. Contact cside support if it continues.

Standard monitoring does not require a customer CNAME or traffic rerouting. If your site has a restrictive Content Security Policy, follow the CSP setup guide to allow *.csidetm.com.

Automatic domain onboarding

Automatic domain onboarding is an optional team capability for deployments that load the standard cside bootstrap script. It is disabled by default for new teams. Contact your cside representative if you need it enabled.

When the capability is enabled and an unregistered hostname loads the team-specific /client.js or /script.js bootstrap, cside submits the referring hostname through the same domain validation and registration flow. Keep the standard referrerpolicy="origin" attribute so the page origin is available without exposing its path or query string.

The request that detects the unregistered hostname is not retried. Registration affects a later script request after configuration has propagated. Automatically registered domains appear in the team’s domain inventory like domains registered through the API.

Automatic onboarding does not create teams, and requests to other cside endpoints do not register a hostname. Use the explicit API workflow when you need a result for every domain before deploying the script. Automatic onboarding applies to the standard monitoring script and does not enable Device Intelligence collection.

List teams

Use GET /v1/teams/ with an organization token. Team-scoped tokens cannot call this endpoint. Omit name to list teams, or provide an exact, case-sensitive name to look one up. Surrounding whitespace is trimmed, as it is during creation. Renamed teams can share a name, so always handle an array of results. Suspended teams are included. No match returns 200 OK with an empty data array.

curl --get \
  --url https://api.cside.com/v1/teams/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --data-urlencode "name=Acme Production"
{
  "data": [
    {
      "id": "1897425263682514944",
      "name": "Acme Production",
      "createdAt": "2026-07-07T10:00:00Z",
      "suspended": false
    }
  ],
  "next_cursor": null
}

List domains

Use GET /v1/domains/ to list domains. With an organization token, omit team_id to read across the organization or set it to select one team. A team-scoped token can read only its own team, even when team_id is omitted. An unknown or inaccessible team returns 404 team_not_found. The optional domain filter matches an exact hostname.

curl --get \
  --url https://api.cside.com/v1/domains/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --data-urlencode "team_id=1897425263682514944"
{
  "data": [
    {
      "id": "1897425263682514945",
      "domain": "checkout.acme.com",
      "teamId": "1897425263682514944",
      "managed": true,
      "wildcard": false,
      "suspended": false,
      "createdAt": "2026-07-07T10:00:00Z"
    }
  ],
  "next_cursor": null
}

Results include managed and unmanaged domains. id is the domainId returned by domain registration. Check managed before using that ID with DELETE /v1/domains/: only managed domains can be deleted through this API. No matching hostname returns an empty data array.

Paging through results

Both endpoints accept limit (1 to 100, default 50) and an optional cursor. Results are ordered by creation time, oldest first, with ID as the tie-breaker. Each 200 OK response contains a data array and next_cursor. Continue until next_cursor is null.

Treat the cursor as opaque and URL-encode it when sending it back. Keep the same token scope and filters between pages. A malformed cursor or one from another query or tenant returns 400 invalid_cursor; restart that query without a cursor.

curl --get \
  --url https://api.cside.com/v1/domains/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --data-urlencode "team_id=1897425263682514944" \
  --data-urlencode "cursor=NEXT_CURSOR"

Delete domains

Use DELETE /v1/domains/ with the domainId values returned by domain registration. Do not send hostnames to this endpoint.

curl --request DELETE \
  --url https://api.cside.com/v1/domains/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "team_id": "1897425263682514944",
    "domains": [
      "1897425263682514945",
      "1897425263682514946"
    ]
  }'

You can send 1 to 100 domain IDs. A successful request returns ordered partial results:

{
  "data": {
    "results": [
      {
        "status": "deleted",
        "domainId": "1897425263682514945",
        "domain": "checkout.example.com"
      },
      {
        "status": "not_found",
        "domainId": "1897425263682514999"
      }
    ],
    "totals": {
      "deleted": 1,
      "not_found": 1
    }
  }
}

Deletion is idempotent. An unknown ID, an already deleted domain, or a domain outside the target team returns not_found without exposing information about another team.

Delete a team

Use DELETE /v1/teams/ to permanently delete a team and all its domains. The request requires an organization-level token with Delete teams (teams:delete). This permission includes domain deletion; domains:delete alone cannot delete a team. Generate a new token to add this permission to an existing integration. Team-scoped tokens are not accepted.

Send the teamId returned by team creation as the quoted decimal string team_id. You do not need to list the team’s domains or delete them separately.

All team domains are deleted

Deletion includes managed, unmanaged, and suspended domains. It removes the team’s domain licenses and configuration. Historical analytics and previously generated reports and CDN files are not erased by this endpoint.

curl --request DELETE \
  --url https://api.cside.com/v1/teams/ \
  --header "Authorization: Bearer $CSIDE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "team_id": "1897425263682514944"
  }'

A successful request returns 200 OK. deletedDomains is the number of domains removed:

{
  "data": {
    "status": "deleted",
    "teamId": "1897425263682514944",
    "deletedDomains": 2
  }
}

A team with an attached Stripe subscription returns 409 team_subscription_attached. Cancel the subscription before deleting the team. If it is already canceled and this error persists, contact cside support.

An unknown team, a team outside the token’s organization, or an already deleted team returns 404 team_not_found. Repeating a successful deletion does not delete anything else. A cleanup failure returns 503 team_deletion_unavailable; retry later and contact support if it continues.

The Enterprise access check applies to every request. If you delete the organization’s last active Enterprise team, subsequent Public API requests, including retries, return 403 enterprise_required.

Request-level errors

Request-level failures use this shape:

{
  "error": "insufficient_scope",
  "message": "Token is missing the domains:create scope."
}
HTTP statusCommon error codesAction
400invalid_request, invalid_payment_pageCheck the JSON body, required fields, ID strings, selector format, and item limits
401unauthorizedCheck the bearer token and whether it was revoked, either on its own or through Revoke all tokens
403insufficient_scope, enterprise_required, suspension or legacy-tier errorsCheck token permissions, plan access, and account status
404team_not_foundConfirm the team ID belongs to the token’s organization
409team_name_existsChoose a unique team name or use the existing team
409team_subscription_attachedCancel the team’s Stripe subscription before deleting it; contact support if the conflict persists
429rate_limitedRetry with backoff after the current rate-limit window
503rate_limit_unavailable, domain_registration_unavailable, domain_deletion_unavailable, team_deletion_unavailable, payment_page_unavailableRetry later; contact cside support if the error continues. Retrying POST /v1/domains/ after domain_registration_unavailable is safe

Security checklist

  • Generate a separate, named token for each backend integration
  • Grant only the permissions that integration needs
  • Store tokens in a server-side secret manager
  • Never expose tokens in browser code, URLs, source control, or logs
  • Revoke a token immediately if it is exposed; use Revoke all tokens when you cannot tell which token leaked or the token predates the token list
  • Review the Last used column and revoke tokens that are no longer in use
  • Treat returned team and domain IDs as strings
Was this page helpful?