> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tamradar.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Keep your system in sync

> Reconcile radar inventory, recover missed updates, and track bulk creation outcomes.

Use this guide after an interrupted sync, a missed creation response, or a
webhook outage. Each endpoint answers a different question:

| What you need | Endpoint | What to store |
| - | - | - |
| Current radar inventory and status | [List Radars](https://docs.tamradar.com/api-reference/list-radars.md) | Radar records, keyed by `radar_id` |
| Findings and radar failures added to your feed | [Poll Updates](https://docs.tamradar.com/api-reference/poll-updates.md) | Updates, keyed by `update_id` |
| Outcomes of a bulk creation submission | [Get Bulk Create Status](https://docs.tamradar.com/api-reference/bulk-status.md) | Per-item outcomes, matched by `bulk_id` and `item_index` |

You do not need to send a list of radar IDs to retrieve your account's inventory
or updates. The examples below cover all radar types.

## Reconcile your radar inventory

Start with a request for up to 500 radars. Omit `radar_status` to include both
active and inactive radars, and omit `created_since` to include older radars.

```bash theme={null}
curl "https://api.tamradar.com/v1/radars?limit=500" \
  -H "x-api-key: YOUR_API_KEY"
```

For each page:

1. Read the radar records from `data`.
2. Insert or update each local record using `radar_id` as its key. Save the
   returned `radar_status`, including `inactive`.
3. If `has_more` is `true`, request the next page with the returned `next_cursor`
   as `cursor`. Repeat until `has_more` is `false`.

```bash theme={null}
curl --get "https://api.tamradar.com/v1/radars" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "limit=500" \
  --data-urlencode "cursor=CURSOR_FROM_PREVIOUS_RESPONSE"
```

Keep any filters unchanged on every page. Treat cursors as opaque: do not parse,
construct, or modify them. The response's `count` is the number of radars on that
page, not the total on your account.

If you supplied your own record ID in `custom_fields` when creating a radar,
use it to connect the returned radar to the record in your system. Keep
`radar_id` as the key for the radar itself.

> [!NOTE]
>
> `created_since` filters creation time only. It does not find older radars whose
> status changed. To refresh their status, list them again without that filter.

A traversal is not a frozen snapshot. Radars created after the first page may
not appear in the remaining pages, and statuses can change during the scan.
Start a fresh traversal to pick up later changes. Do not treat an interrupted
scan as a complete inventory or remove local records just because they have not
appeared yet.

## Recover missed updates

Use polling alongside webhooks, or on its own. Both delivery paths use
`update_id`, so you can store each update once even if it arrives through both.

For the first sync, choose a `since` timestamp for the period you need, or omit
it to retrieve all retained updates. For later syncs, start about one minute
before the bookmark from your last completed sync.

For example, if your saved bookmark is `2026-05-01T08:00:00Z`, start at `07:59:00Z`:

```bash theme={null}
curl --get "https://api.tamradar.com/v1/updates" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode "since=2026-05-01T07:59:00Z" \
  --data-urlencode "limit=100" \
  --data-urlencode "update_type=radar_finding,radar_failure"
```

By default, `GET /v1/updates` returns `radar_finding` only. The example requests
both findings and `radar_failure` updates from the feed.

Use this loop:

1. Keep `since` and all filters fixed for the entire traversal.
2. Store each item in `updates`, deduplicating by `update_id`. Repeated items
   must not trigger the same downstream action twice.
3. While `has_more` is `true`, send `next_cursor` as `cursor` with the same
   `since` and filters.
4. Only after every page is successfully stored, save the highest
   `discovered_at` seen as the new bookmark. If no updates were returned, keep
   the existing bookmark.

Keep the bookmark separate from the pagination cursor. Start each new sync
without a cursor. If you use separate filtered syncs, keep a bookmark for each
filter set. If you change filters to include updates you have not stored, choose
a `since` value that covers the history you need.

> [!WARNING]
>
> Do not advance the bookmark after only the first page or after an interrupted
> traversal. Results are newest first, so doing so could skip the remaining older
> updates. Restart from the previous completed bookmark and deduplicate.

`discovered_at` is the time an update was added to your feed. The one-minute
overlap reduces the risk of missing an update being added while you poll; it is
not a guarantee. Updates are retained for about **60 days**. Poll well within
that window and keep your own copy for longer history. Polling cannot recover
updates that have already been purged.

The polling `since` parameter filters updates already in your feed. It does not
change a radar's `updates_since`, which controls historical source-event
eligibility. See [Poll Updates](https://docs.tamradar.com/api-reference/poll-updates.md) for the full contract.

## Reconcile bulk creation

A `202 Accepted` response means the submission was queued. It does not mean every
radar was created.

1. Save the returned `bulk_id` and your submitted items immediately.
2. Poll `GET /v1/radars/bulk/{bulk_id}` until the top-level `status` is `completed`.
3. Match each item in `radars` to your submitted item using `item_index`, the
   zero-based position within that batch. Use `custom_fields` for your own
   record mapping when supplied.
4. For an item with `status: "success"`, store `data.radar_id`. For an item with
   `status: "error"`, store its `code`, `message`, and `errors` for review. Also
   save `error_id` when present so you can include it in a support request.

```bash theme={null}
curl "https://api.tamradar.com/v1/radars/bulk/YOUR_BULK_ID" \
  -H "x-api-key: YOUR_API_KEY"
```

`completed` means every item has a final outcome, including failures. Finished
items have an `update_id` that matches the item's webhook outcome, so polling
and webhook handling can share the same deduplication key.

A failed attempt to create an item in a bulk submission also uses
`update_type: "radar_failure"`. That creation outcome is returned through bulk
status and configured webhooks, not `GET /v1/updates`. It is separate from the
`radar_failure` updates available in the polling feed.

See the [Bulk Create Guide](https://docs.tamradar.com/guides/bulk-create-guide.md) for submission examples and
[Get Bulk Create Status](https://docs.tamradar.com/api-reference/bulk-status.md) for per-item response fields.

## Resume after an interruption

| Situation | What to do |
| - | - |
| A read request times out, loses its connection, or returns `5xx` or `429` | Retry with backoff. For `429`, follow `Retry-After`. Keep the same cursor and filters while retrying that page. |
| A cursor returns `400` (`Invalid cursor`) | Restart without a cursor, using the same filters and, for updates, the same `since`. Upsert radars or deduplicate updates as usual. |
| Your process stops partway through a sync | Restart the radar scan, or restart updates from the previous completed bookmark. Do not treat partial results as a completed sync. |
| An update arrives again | Deduplicate by `update_id`, whether it came from polling or a webhook. |
| A bulk completion webhook is missing | Poll the saved `bulk_id` and inspect every item's outcome. |

For other errors, follow [Error Handling](https://docs.tamradar.com/guides/error-handling.md). See
[Authentication & Rate Limits](https://docs.tamradar.com/guides/authentication-rate-limits.md) for read
budgets and retry headers.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.