Exclusions API

List, create, update and delete the exclusion rules that stop matching traffic, such as health checks, from being captured by ApiTraffic.

This page as Markdown

An exclusion rule tells your SDK not to capture requests that match its criteria, for example load-balancer health checks or internal traffic. Excluded requests are never sent to ApiTraffic, so they are not stored and do not count toward usage. Rules apply to the buckets and environments you choose. See Exclusions for doing this in the app.

Permissions: any member can list and read rules. Creating, changing and deleting a rule needs an owner or admin, or an administrator API token. Limit: the number of rules an account can create depends on its plan.

Connected SDKs receive rule changes without a restart.

The exclusion object

  • sid (string, required): The rule’s identifier (xcl_ followed by 27 letters and digits).

  • accountSid (string, required): The account.

  • description (string | null): A short description.

  • criteria (string | null, required): Which requests the rule applies to, in the search syntax, for example url_path == "/health". Empty on a body omission rule that applies to all traffic in its buckets and environments.

  • action (string): What a match does (see Rule actions): exclude (the default) or omit_request_body, omit_response_body, omit_bodies.

  • buckets (string[]): The buckets the rule applies to, or ["*"] for all.

  • environments (string[]): The environments the rule applies to, or ["*"] for all.

  • enabled (boolean): Whether the rule is active. Default true.

  • warnings (object[]): Present only when there is something to say. Each has a code, the path it is about (criteria) and a message. criteria-rule-sent-disabled: the rule is enabled, but it is sent to your servers turned off, so it leaves nothing out, because its criteria were saved before the API refused criteria SDKs read differently from what was written (see Criteria SDKs read differently). Change the criteria to turn it back on.

  • createdAt (string): When the rule was created (ISO 8601).

  • updatedAt (string | null): When it was last changed.

List exclusions

GET https://api.apitraffic.io/v1/accounts/{accountSid}/exclusions

Returns every exclusion rule in the account.

Path parameters

  • accountSid (path, string, required): The account identifier.

Response

  • hasMore (boolean, required): Always false: every rule is returned in one response.

  • records (object[], required): The rules, as exclusion objects.

bash
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/exclusions \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/exclusions`, {
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const { records } = await response.json();
json
{
  "hasMore": false,
  "records": [
    {
      "sid": "xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP",
      "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
      "description": "Load balancer health checks",
      "criteria": "url_path == \"/health\"",
      "buckets": ["*"],
      "environments": ["*"],
      "enabled": true,
      "createdAt": "2026-03-02T16:05:00.000Z",
      "updatedAt": null
    }
  ]
}

Get exclusion

GET https://api.apitraffic.io/v1/accounts/{accountSid}/exclusions/{exclusionSid}

Returns one exclusion rule.

Path parameters

  • accountSid (path, string, required): The account identifier.

  • exclusionSid (path, string, required): The rule’s identifier (xcl_…).

Response

An exclusion object.

bash
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/exclusions/xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const exclusionSid = 'xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/exclusions/${exclusionSid}`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const rule = await response.json();
json
{
  "sid": "xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "description": "Load balancer health checks",
  "criteria": "url_path == \"/health\"",
  "buckets": ["*"],
  "environments": ["*"],
  "enabled": true,
  "createdAt": "2026-03-02T16:05:00.000Z",
  "updatedAt": null
}

Create exclusion

POST https://api.apitraffic.io/v1/accounts/{accountSid}/exclusions

Creates an exclusion rule.

Permissions: owner or admin, or an administrator API token. Limit: past the plan’s exclusion rule limit, the API answers 409 with code 2213.

Path parameters

  • accountSid (path, string, required): The account identifier.

Body parameters

  • criteria (body, string): Which requests the rule applies to. Required when action is exclude; a body omission rule may leave it empty to apply to all traffic in its buckets and environments.

  • action (body, string): exclude (the default), omit_request_body, omit_response_body or omit_bodies. See Rule actions.

  • description (body, string | null): A short description.

  • buckets (body, string[]): Bucket sids, or ["*"] for every bucket.

  • environments (body, string[]): Environment sids, or ["*"] for every environment.

  • enabled (body, boolean, default true): Whether the rule is active.

Response

The new exclusion object.

bash
curl -X POST https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/exclusions \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "CORS preflight requests",
    "criteria": "method == \"OPTIONS\"",
    "buckets": ["k3m9p2x"],
    "environments": ["*"],
    "enabled": true
  }'
js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/exclusions`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    description: 'CORS preflight requests',
    criteria: 'method == "OPTIONS"',
    buckets: ['k3m9p2x'],
    environments: ['*'],
    enabled: true,
  }),
});
const rule = await response.json();
json
{
  "sid": "xcl_2mN4bV6cX8zL1kJ3hG5fD7sA9qE",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "description": "CORS preflight requests",
  "criteria": "method == \"OPTIONS\"",
  "buckets": ["k3m9p2x"],
  "environments": ["*"],
  "enabled": true,
  "createdAt": "2026-10-20T09:40:00.000Z",
  "updatedAt": null
}

Update exclusion

PUT https://api.apitraffic.io/v1/accounts/{accountSid}/exclusions/{exclusionSid}

Replaces an exclusion rule. Send the whole rule, with the same fields as Create exclusion. To pause a rule, send it with enabled: false.

Permissions: owner or admin, or an administrator API token.

Path parameters

  • accountSid (path, string, required): The account identifier.

  • exclusionSid (path, string, required): The rule’s identifier.

Body parameters

The same as Create exclusion: criteria is sent (it may be empty only for a body omission rule); action, description, buckets, environments and enabled are optional, and a left-out action keeps the rule’s current one. criteria is checked as on create, even when it is unchanged, so a rule saved before a check existed (with OR, criteria the SDK can’t parse, more than 4,096 characters, more than 256 spaces in a row, or criteria SDKs read differently) can’t be updated, paused included, until its criteria pass: replace OR with AND to keep what such a rule does (it has always run as AND), or delete the rule.

Response

The updated exclusion object.

bash
curl -X PUT https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/exclusions/xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Health and readiness checks",
    "criteria": "url_path like \"^/(health|ready)$\"",
    "buckets": ["*"],
    "environments": ["*"],
    "enabled": true
  }'
js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const exclusionSid = 'xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/exclusions/${exclusionSid}`,
  {
    method: 'PUT',
    headers: {
      Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      description: 'Health and readiness checks',
      criteria: 'url_path like "^/(health|ready)$"',
      buckets: ['*'],
      environments: ['*'],
      enabled: true,
    }),
  },
);
const rule = await response.json();
json
{
  "sid": "xcl_2zX4cV6bN8mA1sD3fG5hJ7kL9qP",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "description": "Health and readiness checks",
  "criteria": "url_path like \"^/(health|ready)$\"",
  "buckets": ["*"],
  "environments": ["*"],
  "enabled": true,
  "createdAt": "2026-03-02T16:05:00.000Z",
  "updatedAt": "2026-10-20T09:45:00.000Z"
}

Delete exclusion

DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/exclusions/{exclusionSid}

Deletes an exclusion rule. Matching requests are captured again from then on.

Permissions: owner or admin, or an administrator API token.

Path parameters

  • accountSid (path, string, required): The account identifier.

  • exclusionSid (path, string, required): The rule’s identifier.

Response

  • sid (string, required): The deleted rule’s identifier.

  • deleted (boolean, required): true.

bash
curl -X DELETE https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/exclusions/xcl_2mN4bV6cX8zL1kJ3hG5fD7sA9qE \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const exclusionSid = 'xcl_2mN4bV6cX8zL1kJ3hG5fD7sA9qE';
await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/exclusions/${exclusionSid}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
json
{
  "sid": "xcl_2mN4bV6cX8zL1kJ3hG5fD7sA9qE",
  "deleted": true
}

Rule actions

action Effect
exclude (default) The request is not sent to ApiTraffic at all.
omit_request_body The request is logged without its request body.
omit_response_body The request is logged without its response body.
omit_bodies The request is logged without either body.

A body left out by a rule is never stored, but its size is still recorded, so request_size and response_size stay accurate. The request’s omittedBodies field ({ "request": "xcl_…", "response": null }) names the rule, and the request view says the body was not logged.

Body omission rules are enforced by your SDK and again by ApiTraffic before anything is stored, so their criteria are limited to what both read the same way: besides the checks below, no endpoint conditions, no > < >= <= on a header, query parameter or tag, and no like pattern with a lookaround or backreference. Other criteria are refused with a 400.

Regular expressions in criteria

An exclusion’s criteria is a query such as url_path like "^/health" AND method == "GET". The value of each like condition is a regular expression: one leading * is removed, and the rest is compiled as new RegExp(value) (no flags, so it is case-sensitive) and tested against the request field inside your application.

Because that runs on every captured request in your servers, each like pattern is checked when the exclusion is created or updated. The request is refused with 400 (code 1000) if a pattern does not compile, is longer than 512 characters, or can backtrack catastrophically (for example (a+)+$, (\w+\s?)+ or an unanchored .*\.png$). SDK releases before the criteria parser update read \" and \\ in a quoted value literally (a backslash, and the quote dropped), so a pattern is checked as they read it too; the message then says so. The message names the condition and the fix:

json
{
  "message": "criteria: condition \"url_path like (a+)+$\": Pattern nests one repetition inside another, which can take exponential time. Remove the inner or outer quantifier, or start each repeated group with a character the group cannot otherwise match (for example \"(?:\\.[a-z]+)*\").",
  "code": 1000,
  "moreInformation": "https://apitraffic.io/api/errors/1000",
  "data": {}
}

The SDK also bounds what it runs: each pattern is compiled once, an invalid pattern never matches (it never throws), and only the first 2,048 characters of a value are tested. A match that lies entirely beyond that is not seen, and a $ anchor applies to the end of those 2,048 characters for longer values.

Criteria SDKs read differently

Exclusions run in your servers, on whatever SDK release each one runs, so criteria that SDKs read differently from the search syntax are refused with 400 (code 1000):

  • A leading - or ! on a condition. SDK releases before the current one ignore it, so -method == "OPTIONS" would leave out the OPTIONS requests instead of everything else. Write the opposite condition: method != "OPTIONS".
  • >, >=, < or <= on a value the SDK holds as text: request_header, response_header, query_param, tag, request_size and response_size (read from the Content-Length header), waf_score, and text fields such as url_path or method. SDK releases before the current one compare those as text ("999" is greater than "1000"); the current release compares headers, query parameters, tags and waf_score as numbers, but the rule is the same for every SDK version. Ordered comparisons on status_code, duration, the APM rollups and the server fields (concurrency, event_loop_delay_ms) compare numbers and are accepted.
  • Any condition on received, whatever the operator. SDK releases before the current one never read the time a request was received, so a condition on it never matches there (the rule leaves nothing out), and received != … matches every request (the rule leaves out everything). To exclude requests for a period, enable the rule at its start and disable it at its end (Update exclusion).
  • Any condition on capture. It marks captures, requests sent to the bucket’s capture URL, which never pass through an SDK, so every request an exclusion sees is capture == false. SDK releases before the current one read no value for it: capture == false never matches there, and capture != false matches every request. The current release does not accept it.
json
{
  "message": "criteria: criteria \"-method == OPTIONS\": \"-method == OPTIONS\": SDKs before the current release ignore a leading - or ! and would leave out the requests that match what follows instead; write the opposite condition without it (method != GET, not -method == GET).",
  "code": 1000,
  "moreInformation": "https://apitraffic.io/api/errors/1000",
  "data": {}
}

A rule saved with such criteria before the API refused them is sent to your servers turned off (it leaves nothing out), and carries a criteria-rule-sent-disabled warning. It can be deleted, or updated once its criteria pass.

Common exclusion criteria

To leave out criteria
Health checks url_path == "/health"
Health and readiness checks url_path like "^/(health|ready)$"
CORS preflight requests method == "OPTIONS"
Static assets url_path like "^/static/"
Calls your API makes to one internal service direction == "out" AND host == "inventory.acme-internal.example"
A monitoring agent request_header:user-agent like "^acme-lb-healthcheck/"

Errors

Status Code Meaning
400 1000 A field is missing or invalid, including a criteria that cannot be parsed or a like pattern that fails the checks above.
403 2010 Creating, changing or deleting a rule without owner, admin or administrator access.
404 4000 No rule with that exclusionSid in this account.
409 2213 The plan’s exclusion rule limit is reached.