Outbound destinations API

Review the hosts your app calls out to, approve or flag them, manage approve and flag rules, turn destination watch on per bucket and choose which environments are production.

This page as Markdown

Destination watch keeps a list of every host each bucket’s app calls, and alerts the first time it calls a new one. See Watch for new outbound destinations for how it works in the app.

Plan: needs a plan that includes Outbound destination watch. Reading destinations, rules, watch state and environments keeps working if the plan changes. Permissions: any member, or a user or administrator API token, can read and review destinations. Rules, turning watch on or off, pruning and the production marker need an owner or admin, or an administrator API token.

Destinations are kept per bucket: the same host called from two buckets is two destinations. Hosts are canonical: lowercase, internationalized names in punycode, IPv6 addresses in brackets, no port.

The destination object

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

  • bucketSid (string, required): The bucket that calls it.

  • host (string, required): The canonical hostname.

  • domain (string, required): The registrable domain, from the ICANN section of the Public Suffix List. For an IP address, the address.

  • sharedSuffix (string | null): The shared-hosting suffix the host sits under (for example herokuapp.com), where anyone can create hosts. An approve wildcard never covers it.

  • kind (string, required): name, ipv4, ipv6, localhost, private or metadata.

  • status (string, required): pending (in the review queue), approved, flagged or baselined (approved by the import that ran when watch was turned on).

  • ports (integer[], required): Non-default ports seen, up to 16.

  • portsOverflow (boolean, required): More than 16 non-default ports were seen.

  • sources (string[], required): Where the host was learned from: sdk (outbound records) and span (http.out spans).

  • environments (object[], required): Live sightings, one per environment: environmentSid, name, isProduction, firstSeenAt and lastSeenAt.

  • historyEnvironments (object[], required): The same, for sightings found by the import that ran when watch was turned on.

  • firstSeenAt (string | null): When the host was first called (ISO 8601).

  • lastSeenAt (string | null): When it was last called.

  • firstRequestSid (string | null): The request that first called it.

  • firstTrigger (object | null): The inbound route whose handler made the first call (inboundMethod, inboundEndpoint) when the call was seen inside a request; {"history": true} for a host found by the enablement import, {"recovered": true} for one recovered from stored traffic, and null when it isn’t known (a host first seen on its own outbound record).

  • correlatedEventSid (string | null): The deploy event in the hour before the first call, if any.

  • risk (object, required): reasons: any of ip_literal, ip_encoding, metadata_endpoint, non_ascii, non_standard_port and flag_rule. A host with a reason is never approved by a rule or the import. notes: details about how the host was read.

  • callsTotal (integer, required): Calls seen so far. Approximate.

  • alertState (object, required): The host’s alerts, one for production (prod) and one for every other environment (preprod): each a state (firing or resolved) and the time at.

  • alertDeferred (boolean, required): The host’s alert is waiting for the import that runs when watch is turned on.

  • reviewedBy (string | null): Who last reviewed it.

  • reviewedAt (string | null): When.

  • reviewNote (string | null): The note left with the last review.

  • flaggedAt (string | null): When it was flagged.

  • flaggedByRuleSid (string | null): The flag rule that flagged it.

  • approvedByRuleSid (string | null): The approve rule that approved it.

  • createdAt (string | null): When it was added.

List destinations

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

Lists destinations, newest first. status=pending,flagged is the review queue.

Path parameters

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

Query parameters

  • bucketSid (query, string): Only this bucket.

  • environmentSid (query, string): Only hosts this environment called.

  • status (query, string): Comma separated: pending, approved, flagged, baselined.

  • kind (query, string): name, ipv4, ipv6, localhost, private or metadata.

  • domain (query, string): A registrable domain or shared suffix.

  • q (query, string): Part of the host.

  • risk (query, string): Only hosts with this risk reason.

  • limit (query, integer, default 100): 1 to 500.

  • cursor (query, string): nextCursor from the previous page.

Response

records, a list of destination objects, hasMore and nextCursor.

bash
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations?bucketSid=k3m9p2x&status=pending,flagged" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
json
{
  "hasMore": false,
  "nextCursor": null,
  "records": [
    {
      "sid": "dst_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
      "bucketSid": "k3m9p2x",
      "host": "telemetry.leftpad-analytics.io",
      "domain": "leftpad-analytics.io",
      "sharedSuffix": null,
      "kind": "name",
      "status": "pending",
      "ports": [],
      "portsOverflow": false,
      "sources": ["sdk"],
      "environments": [
        { "environmentSid": "env_2pQ7rS9tU1vW3xY5zA7bC9dE1fG", "name": "production", "isProduction": true,
          "firstSeenAt": "2026-10-29T10:02:11.000Z", "lastSeenAt": "2026-10-29T11:40:03.000Z" }
      ],
      "historyEnvironments": [],
      "firstSeenAt": "2026-10-29T10:02:11.000Z",
      "lastSeenAt": "2026-10-29T11:40:03.000Z",
      "firstRequestSid": "req_2nB5cD7eF9gH1jK3lM5nP7qR9sT",
      "firstTrigger": { "inboundMethod": "POST", "inboundEndpoint": "/v1/checkout" },
      "correlatedEventSid": "evt_2rT6uV8wX1yZ3aB5cD7eF9gH1jK",
      "risk": { "reasons": [], "notes": [] },
      "callsTotal": 184,
      "alertState": { "prod": { "state": "firing", "at": "2026-10-29T10:02:26.000Z" } },
      "alertDeferred": false,
      "reviewedBy": null,
      "reviewedAt": null,
      "reviewNote": null,
      "flaggedAt": null,
      "flaggedByRuleSid": null,
      "approvedByRuleSid": null,
      "createdAt": "2026-10-29T10:02:26.000Z"
    }
  ]
}

Get destination

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

Path parameters

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

  • destinationSid (path, string, required): The destination’s identifier.

Response

The destination object, with history: each review, rule application and automatic change (action, actor, reason, note, at), newest first, up to 100.

bash
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/dst_2kM4nP6qR8sT1uV3wX5yZ7aB9cD" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"

Review destination

PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/destinations/{destinationSid}

Approves, flags or reopens one destination. Approving resolves its alerts. Flagging alerts at critical severity until the host has gone 24 hours without a call.

Path parameters

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

  • destinationSid (path, string, required): The destination’s identifier.

Body parameters

  • status (body, string, required): approved, flagged or pending (reopen).

  • note (body, string): Up to 500 characters. Required to flag.

Response

The updated destination object. Approving a host a flag rule flagged needs an owner or admin; anyone else gets 403.

bash
curl -X PATCH "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/dst_2kM4nP6qR8sT1uV3wX5yZ7aB9cD" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "flagged", "note": "Not a service we use" }'

Review destinations in bulk

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

The same review for up to 500 destinations at once. All or nothing: if one can’t be changed, none are.

Path parameters

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

Body parameters

  • sids (body, string[], required): 1 to 500 destination identifiers.

  • status (body, string, required): approved, flagged or pending.

  • note (body, string): Required to flag.

Response

records, the updated destination objects.

bash
curl -X POST "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/review" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "sids": ["dst_2kM4nP6qR8sT1uV3wX5yZ7aB9cD"], "status": "approved" }'

Prune destinations

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

Deletes destinations that are no longer called, to make room under the limits. Approved and baselined destinations by default. Pending ones only after 30 days without a call, and only with a note. Flagged destinations are never pruned. A pruned host that is called again is new again.

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

Path parameters

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

Body parameters

  • bucketSid (body, string): Only this bucket.

  • sids (body, string[]): Only these destinations (up to 500).

  • statuses (body, string[]): Any of approved, baselined and pending.

  • notSeenForDays (body, integer): Only destinations not called for this many days. Required unless sids is given, and at least 30 to prune pending destinations.

  • note (body, string): Required when pruning pending destinations.

Response

deleted, how many destinations were deleted (at most 500 per call), and hasMore: when true, more match, so call again.

bash
curl -X POST "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/prune" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "bucketSid": "k3m9p2x", "notSeenForDays": 90 }'
json
{ "deleted": 12, "hasMore": false }

The rule object

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

  • pattern (string, required): An exact host, or *.domain for a domain and every name under it.

  • effect (string, required): approve or flag. Flag beats approve.

  • bucketSids (string[] | null): Only these buckets; null means every bucket.

  • note (string | null): Why the rule exists.

  • createdBy (string | null): Who created it.

  • createdAt (string | null): When.

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

  • applied (integer): On create and update only: how many existing destinations the save changed.

List rules

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

Path parameters

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

Response

records, a list of rule objects.

bash
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinationRules" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"

Preview rule

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

Shows which current destinations a rule would change, without saving it.

Path parameters

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

Body parameters

The same as Create rule.

Response

pattern (as it would be saved), matching (destinations the pattern matches), changing (those saving it would change) and sample, up to 50 of them (sid, host, status).

bash
curl -X POST "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinationRules/preview" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "pattern": "*.stripe.com", "effect": "approve" }'
json
{
  "pattern": "*.stripe.com",
  "matching": 3,
  "changing": 2,
  "sample": [
    { "sid": "dst_2kM4nP6qR8sT1uV3wX5yZ7aB9cD", "host": "api.stripe.com", "status": "pending" }
  ]
}

Create rule

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

Creates a rule and applies it to existing destinations straight away: a flag rule flags every matching destination; an approve rule approves matching pending ones without a risk reason.

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

Path parameters

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

Body parameters

  • pattern (body, string, required): An exact host (api.stripe.com) or *.domain (*.stripe.com). An approve wildcard over a shared-hosting suffix (*.herokuapp.com) or a public suffix (*.com) is refused with 400.

  • effect (body, string, required): approve or flag.

  • bucketSids (body, string[]): Only these buckets (up to 200). Leave out for every bucket.

  • note (body, string): Up to 500 characters.

Response

The rule object, with applied.

bash
curl -X POST "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinationRules" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "pattern": "*.stripe.com", "effect": "approve", "note": "Payments provider" }'
json
{
  "sid": "dsr_2kM4nP6qR8sT1uV3wX5yZ7aB9cE",
  "pattern": "*.stripe.com",
  "effect": "approve",
  "bucketSids": null,
  "note": "Payments provider",
  "createdBy": "usr_2aB4cD6eF8gH1jK3lM5nP7qR9sT",
  "createdAt": "2026-10-29T12:00:00.000Z",
  "updatedAt": "2026-10-29T12:00:00.000Z",
  "applied": 2
}

Update rule

PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/destinationRules/{ruleSid}

Changes any of a rule’s fields. When the pattern, effect or buckets change, the rule is applied again: hosts it no longer covers lose the rule’s flag (they stay flagged, and members can review them again), and hosts it still covers keep it, along with any admin’s approval over it. Changing only the note applies nothing.

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

Path parameters

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

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

Body parameters

Any of pattern, effect, bucketSids and note, as in Create rule.

Response

The rule object, with applied.

bash
curl -X PATCH "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinationRules/dsr_2kM4nP6qR8sT1uV3wX5yZ7aB9cE" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Payments and billing" }'

Delete rule

DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/destinationRules/{ruleSid}

Destinations a deleted flag rule flagged stay flagged, and members can review them again.

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

Path parameters

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

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

Response

sid and deleted: true.

bash
curl -X DELETE "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinationRules/dsr_2kM4nP6qR8sT1uV3wX5yZ7aB9cE" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"

The watch object

  • bucketSid (string, required): The bucket.

  • state (string, required): off, backfilling (importing the last 30 days of hosts), releasing (finishing the import) or watching.

  • enabled (boolean, required): Whether watch is on.

  • startedAt (string | null): When watch was last turned on.

  • backfillMode (string, required): baseline or review_all: what the import does with the hosts it finds.

  • reconciledAt (string | null): When stored history was last checked for hosts live capture missed.

Get bucket watch

GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/destinationWatch

Path parameters

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

  • bucketSid (path, string, required): The bucket identifier.

Response

The watch object.

bash
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/destinationWatch" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"

Update bucket watch

PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/destinationWatch

Turns watch on or off for a bucket. Turning it on imports the last 30 days of hosts first, so an existing app doesn’t start with every host it calls alerting as new. Alerts for new hosts wait for the import, at most 30 minutes; risky hosts alert straight away. Turning it off resolves the bucket’s destination alerts and keeps its destinations.

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

Path parameters

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

  • bucketSid (path, string, required): The bucket identifier.

Body parameters

  • enabled (body, boolean, required): true to turn watch on, false to turn it off.

  • backfillMode (body, string, default baseline): baseline approves the imported hosts (apart from risky ones); review_all puts every one in the review queue.

Response

The watch object.

bash
curl -X PATCH "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/destinationWatch" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "backfillMode": "baseline" }'
json
{
  "bucketSid": "k3m9p2x",
  "state": "backfilling",
  "enabled": true,
  "startedAt": "2026-10-29T12:05:00.000Z",
  "backfillMode": "baseline",
  "reconciledAt": null
}

List environments

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

Lists the account’s environments and whether each counts as production for destination alerts. A host first called from production alerts at a higher severity.

Path parameters

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

Response

records: each environmentSid, name, isProduction and source (inferred from the environment’s name, or manual).

bash
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/environments" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"

Mark environment as production

PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/destinations/environments/{environmentSid}

A choice made here is kept, and never replaced by inference from the environment’s name.

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

Path parameters

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

  • environmentSid (path, string, required): The environment identifier.

Body parameters

  • isProduction (body, boolean, required): Whether the environment is production.

Response

The environment’s record, with source: "manual".

bash
curl -X PATCH "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/destinations/environments/env_2pQ7rS9tU1vW3xY5zA7bC9dE1fG" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "isProduction": true }'

Events

Every review, rule change, watch change and production marker is recorded in the account’s activity and sent to webhooks as a security.destination_* event. See the webhook event reference.