OneCloud API Best Practices


Token Lifecycle Management

Access Tokens

Access tokens are valid for 1 hour while refresh tokens are valid for 24 hours. Please use an access token until it has fully expired then use the refresh token to obtain a new one.

JWT Tokens

JWT tokens are recommended over access tokens and can be decrypted using the jwks file to establish when the token expires. When the token expires, you will need to obtain a new token.

API Keys

API keys can be requested that are valid for an extended time and do not require refresh tokens. This is good for machine-to-machine applications.


Rate Limiting

Thresholds

The OneCloud platform enforces rate limiting at the network level. Exceeding these limits will result in your IP being temporarily blocked with an HTTP 403 response for all http requests — not just the offending endpoint.

These thresholds vary by server configuration. There is no warning before a block is applied — the block takes effect immediately.

Backoff Strategy

If you receive a 403 or 429 response, stop making requests and wait before retrying. Use exponential backoff (e.g., 1s, 2s, 4s, 8s) rather than retrying immediately, as immediate retries will extend the block duration.


Request Requirements

Allowed HTTP Methods

Only the following HTTP methods are accepted:

GET HEAD POST OPTIONS PUT PATCH DELETE

Requests using other methods (e.g., TRACE, CONNECT) will be blocked.

Allowed Content Types

Requests must use one of the following content types:

  • application/json (recommended)
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/xml
  • application/xml

Requests with unsupported content types will be rejected.

Request Body Size

The maximum request body size is 25 MB (26,214,400 bytes). Requests exceeding this limit will receive an HTTP 400 response.

Request Body Formatting

Request bodies must be well-formed. Malformed JSON or XML payloads will be rejected with an HTTP 400 response. Multipart form boundaries must also be strictly valid.


Data Retrieval

Pagination

Always paginate list endpoints. Never attempt to retrieve an entire dataset in a single request. Use limit and offset parameters to fetch data in bounded pages (e.g., 50-200 records per request).

GET /ns-api/v2/resource?limit=100&offset=0
GET /ns-api/v2/resource?limit=100&offset=100

Avoid Unbounded Loops

Do not use forEach or similar loop patterns that fire many parallel API requests. This will quickly exceed rate limits and result in your IP being blocked.

// BAD - fires all requests at once, will trigger rate limiting (HTTP 403)
items.forEach(item => fetch(`/ns-api/v2/resource/${item.id}`));

Instead:

  • Use list endpoints with filters to retrieve multiple records in a single request rather than fetching them individually.
  • Serialize requests if you must loop — process one at a time with a delay between each.
  • Use server-side filtering to reduce the dataset at the source.
// GOOD - single request with server-side filtering
const response = await fetch('/ns-api/v2/resource?filter=domain+eq+example.com&limit=100&offset=0');
// ACCEPTABLE - sequential requests with delay
for (const item of items) {
  await fetch(`/ns-api/v2/resource/${item.id}`);
  await new Promise(resolve => setTimeout(resolve, 100)); // 100ms delay
}

CDR and Stats Retrieval

Call Detail Records and statistics endpoints can return very large datasets. Pulling unbounded CDR or stats queries is one of the most common causes of rate limiting, timeouts, and degraded platform performance.

Always Constrain Your Date Range

Never query CDRs or stats without a date range. Use the narrowest window that meets your needs.

// BAD - no date range, attempts to pull all historical CDRs
GET /ns-api/v2/cdrs?domain=example.com

// GOOD - constrained to a single day
GET /ns-api/v2/cdrs?domain=example.com&time_start=ge(2026-04-01T00:00:00)&time_start=le(2026-04-01T23:59:59)

Recommended maximums:

  • CDR queries: 24 hours per request
  • Stats/analytics queries: 7 days per request

If you need a larger window, break it into multiple smaller requests processed sequentially.

Paginate CDR Results

CDR endpoints can return thousands of records even for a single day. Always use start and limit to paginate results.

GET /ns-api/v2/cdrs?domain=example.com&time_start=ge(2026-04-01T00:00:00)&time_start=le(2026-04-01T23:59:59)&start=1&limit=200

Do Not Loop CDRs Per User

A common anti-pattern is looping through every user or extension to pull individual CDRs. This generates hundreds or thousands of API calls when a single domain-level query with filters would return the same data.

// BAD - one API call per user, will trigger rate limiting
users.forEach(user => fetch(`/ns-api/v2/cdrs?user=${user.id}&limit=1000`));

// GOOD - single query filtered by domain, paginated
GET /ns-api/v2/cdrs?domain=example.com&time_start=ge(2026-04-01T00:00:00)&time_start=le(2026-04-01T23:59:59)&start=1&limit=200

Do Not Poll CDRs for Real-Time Data

CDRs are post-call records. If you need real-time call activity, use WebSockets or Event Subscriptions instead of repeatedly polling the CDR endpoint. Polling CDRs every few seconds will result in connection termination.

Stats Aggregation

When pulling statistics, use the highest level of aggregation that meets your needs. Requesting per-extension stats across an entire reseller territory when you only need domain-level totals wastes resources and may time out.

  • Query at the domain level, not the user level, when possible.
  • Use date-bounded requests — avoid open-ended stat pulls.
  • Cache results client-side rather than re-fetching the same data repeatedly.

Polling

We do not allow excessive polling of the OneCloud APIs. If we detect excessive amounts of polling, we will terminate any connections without notice. You may receive a 429 or 403 from your IP when this happens.

WebSockets

We recommend the use of WebSocket connections for real-time data retrieval inside a client application. Socket event listeners will need to be configured on the client application side to respond to updates. This is recommended for always-on client applications.

Subscriptions

We recommend the use of subscriptions when using the APIs for server-to-server communication. Subscriptions will require a callback URL where subscription events will be posted to.


Error Reference

HTTP StatusCauseAction
400Malformed JSON/XML, oversized request body, invalid multipart boundaryFix the request format or reduce payload size
403Rate limit exceeded or WAF block — your IP is temporarily blocked for all requestsStop all requests, wait for the block to expire, then retry with backoff
429Excessive polling detected at the application levelReduce request frequency, switch to WebSockets or subscriptions

What’s Next