Test your integration

View as Markdown

Before going live, validate that your integration handles the full range of API behaviors—successful responses, errors, pagination, rate limits, and idempotency. This guide covers practical techniques for testing each area and cleaning up afterward.

Request a sandbox environment

Tabs provides sandbox environments for development and testing. Contact your Tabs Implementation or Customer Success Manager to request access.

Review the steps in this guide against your sandbox environment before pointing your integration at production.

Verify your API key

Start by confirming that your API key is valid and scoped to the correct merchant. A simple way to test this is to list your customers:

$curl -s \
> "https://integrators.prod.api.tabsplatform.com/v3/customers?page=1&limit=1" \
> -H "Authorization: YOUR_API_KEY"

A successful response returns 200 OK with a "success": true envelope. If the key is invalid or expired, Tabs returns 401 Unauthorized.

Validate response envelopes

Tabs API responses typically use the same envelope structure. Your integration should parse this envelope consistently rather than assuming the shape of the payload field:

1{
2 "payload": { ... },
3 "success": true,
4 "message": "Operation successful"
5}

Build your response parser to:

  • Check success before accessing payload
  • Log message for debugging
  • Handle cases where payload is null (error responses)

Handle errors gracefully

Test your integration against each error class the API can return. A well-built integration distinguishes between client errors (fix but don’t retry) and server errors (safe to retry).

Test a validation error

Send a request with a missing required field to verify your error handling. For example, create a customer without a name:

$curl -s -X POST \
> https://integrators.prod.api.tabsplatform.com/v3/customers \
> -H "Authorization: YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{}'

Tabs returns a 400 Bad Request with field-level details:

1{
2 "payload": null,
3 "success": false,
4 "message": "Validation failed",
5 "error": {
6 "code": 400,
7 "message": "Validation failed",
8 "details": {
9 "name": ["name must be a string"]
10 }
11 }
12}

Implement a retry strategy

Retry only on transient failures. The following status codes are safe to retry, with the exception of requests to (re)generate invoices:

StatusRetry?Action
400NoFix the request. The details object identifies the invalid fields.
401NoCheck your API key. Do not retry with the same credentials.
404NoThe resource does not exist. Verify the ID.
429YesRate limit exceeded. Retry with exponential backoff.
503YesTransient failure.

Use exponential backoff with jitter for retries. A reasonable starting point is to wait 1 second after the first failure, doubling each subsequent attempt up to a maximum of 30 seconds.

Test pagination

If your integration consumes list endpoints, verify that it handles multi-page responses correctly. Create a small limit and enough test records to exceed a single page, then paginate through them:

$# Fetch page 1
$curl -s \
> "https://integrators.prod.api.tabsplatform.com/v3/customers?page=1&limit=10" \
> -H "Authorization: YOUR_API_KEY"
$
$# Fetch page 2
$curl -s \
> "https://integrators.prod.api.tabsplatform.com/v3/customers?page=2&limit=10" \
> -H "Authorization: YOUR_API_KEY"

Verify that:

  • totalItems remains consistent across pages.
  • currentPage increments correctly.
  • The final page returns the same or fewer items than limit (or an empty data array).

Test rate limit handling

The API generally enforces a rate limit of 10 requests per second per merchant. When the limit is exceeded, Tabs returns 429 Too Many Requests. Your integration should handle this by retrying with exponential backoff.

To test your rate limit handling, send a burst of requests in quick succession and verify that your integration:

  • Detects the 429 status code
  • Pauses before retrying (not immediately re-sending)
  • Succeeds on the retry after backing off

The usage events endpoint (POST /v1/events) has a separate, higher limit of 10,000 requests per minute.

Test idempotency

Usage events are the main write path where idempotency matters—a retried or duplicated request must not double-count usage. Each event Tabs records is assigned an idempotency key, returned as the event’s id in the create response. Use that key to act on the same logical event exactly once.

To test idempotency in your integration:

  1. Create a usage event and capture the id (its idempotency key) from the response.
  2. Delete the event by that key: DELETE /v1/events/{idempotencyKey}.
  3. Verify the customer’s usage total reflects the event exactly once—never doubled by a retried submission.

The Tabs API does not accept a client-supplied Idempotency-Key header. For usage events, the server-assigned key (the event id) is the idempotency handle—capture it on create so a retry can reconcile rather than blindly re-submit.