---
title: "ProducerSync API: Best Practices"
url: "https://developer.agentsync.io/producersync-api-best-practices"
image: "https://developer.agentsync.io/_og/d/c_Ocean.takumi,title_~UHJvZHVjZXJTeW5jIEFQSTogQmVzdCBQcmFjdGljZXM,props_eyJ0aGVtZSI6eyJtb2RlIjoibGlnaHQiLCJjb2xvcnMiOnsicHJpbWFyeSI6IiMxODdFRkYifX19,p_Ii9wcm9kdWNlcnN5bmMtYXBpLWJlc3QtcHJhY3RpY2VzIg,s_n0Egq-bC1U8cyIfa.png"
---

# ProducerSync API: Best Practices

## [Onboarding and Adding New NPNs to Your Subscribed Population](#onboarding-and-adding-new-npns-to-your-subscribed-population)

Due to the nature of data availability, we recommend that NPNs remain subscribed for the duration of time that any NIPR data about the NPN is needed.

### [Benefits of subscribing:](#benefits-of-subscribing)

-   **Performance**: Subscribed NPNs return data quickly (P90 <1s), while non-subscribed NPNs can take over 10s.
-   **Simplicity**: Simplifies calling patterns and available options.

## [Initial Onboarding](#initial-onboarding)

Use a POST call to `/v1/accounts/subscriptions` to set your initial NPN population. POST replaces your entire subscription list with exactly the NPNs you provide — use this when establishing your monitored population for the first time or when you need to reset to a known state.

> **Subscription operations are asynchronous.** POST, PUT, and DELETE return a `job_id` immediately. Check the job status at `GET /v1/accounts/subscriptions/status/{jobId}` to confirm completion before assuming your subscriptions are active.

**Example:**

```bash
curl --request POST \
  --url https://api.sandbox.agentsync.io/v1/accounts/subscriptions \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '["15645555", "19855109"]'
```

If your NPN population exceeds 50,000, we recommend reaching out to your AgentSync Customer Success Manager before "go-live." They can help streamline the onboarding process so that on Day 1, all relevant license, appointment, and other NIPR data is immediately available.

## [Subscribing at Scale](#subscribing-at-scale)

When subscribing a large NPN population, follow these guidelines:

-   **Send up to ~25,000 NPNs per request.** AgentSync automatically splits each request into parallel batches behind the scenes — you don't need to chunk smaller than that yourself.
-   **Wait for each job to complete before sending the next request.** Poll `GET /v1/accounts/subscriptions/status/{jobId}` until the job finishes, then submit your next batch.
-   **Send each list once.** Every submission creates a new job — re-sending the same list doesn't speed anything up. If you lose track of a job, poll the `job_id` you already have.
-   **Format NPNs correctly and de-duplicate.** NPNs must be numeric strings, at most 10 digits, with no leading zeros. Lists containing duplicates or malformed NPNs are rejected as a whole, so validate before sending.

### [How long will it take?](#how-long-will-it-take)

Subscription jobs retrieve producer data from NIPR as they run. Completion time scales with the size of the batch — small batches typically finish in minutes, while large batches can take a few hours.

Poll the job status endpoint for progress — the per-NPN details tell you exactly where things stand.

### [Understanding Per-NPN Job Results](#understanding-per-npn-job-results)

`GET /v1/accounts/subscriptions/status/{jobId}/details` returns a status and message for each NPN. Two messages are commonly misread:

| Message                                      | Status  | What it means                                                                    |
| :------------------------------------------- | :------ | :------------------------------------------------------------------------------- |
| Entity skipped: already exists in database   | SUCCESS | Not an error. The subscription is active — no action needed.                     |
| No producer data found for entity id '{npn}' | FAILED  | NIPR has no record of this NPN. The number is invalid or the producer no longer exists in NIPR — verify the NPN. |

### [Keep Invalid NPNs Out of Your Sync List](#keep-invalid-npns-out-of-your-sync-list)

If an NPN fails with "No producer data found," **remove it from your source system** rather than re-submitting it on your next sync. Producers deleted from NIPR that are repeatedly re-subscribed will appear in your population briefly and then drop out again — an endless churn loop that creates confusing noise in your subscription list and webhook events.

## [Checking an NPN Without Subscribing](#checking-an-npn-without-subscribing)

To verify a producer exists before adding them to your monitored population, use the lookup endpoint:

```bash
POST /v1/npn/lookup
```

Lookups accept up to 10 entries per request and do **not** change your subscriptions.

> Avoid using `GET /v1/entities/{npn}` as an existence check: requesting a producer you aren't subscribed to through that endpoint **automatically subscribes them to your account**. If you only need read access, ask AgentSync Support about a read-only credential, which never auto-subscribes.

## [Ongoing Subscriptions](#ongoing-subscriptions)

Subscriptions can be maintained using the `/accounts/subscriptions` endpoint.

**Best practice:**

-   Use a PUT call to `/v1/accounts/subscriptions` whenever you need to add new NPNs to your monitored population. PUT **appends** to your existing list — it does not remove any currently subscribed NPNs.
-   This allows AgentSync to request and process data from NIPR ahead of subsequent calls, reducing latency.

> PUT, POST, and DELETE are asynchronous. Each returns a `job_id` — poll `GET /v1/accounts/subscriptions/status/{jobId}` to confirm the operation completed before making dependent API calls.

**Example:**

```bash
curl --request PUT \
  --url https://api.sandbox.agentsync.io/v1/accounts/subscriptions \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '["15645555"]'
```

Subscribing an NPN in advance ensures that subsequent requests (e.g., `GET /v2/entities/{NPN}/licenses`) return faster.

## [Maintaining Producer Updates for Your Subscribed Population](#maintaining-producer-updates-for-your-subscribed-population)

Because of the volume of data requested, do not pull the full dataset daily. This may cause:

-   Performance degradation
-   AgentSync rate limiting
-   Large latencies

### [Recommended Best Practice](#recommended-best-practice)

1.  Make an initial request for the NPN to pull the full dataset.
2.  Persist this data in your system.
3.  On a daily basis, use the `producersync.updates_available` webhook event to trigger API calls.
4.  Use the `updatedSince` query parameter with today's date (this date will increment automatically).
5.  This significantly reduces redundant information.
6.  If not using the webhook event, set `updatedSince = (today's date - 1)` to account for potential NIPR update delays.
7.  Process changes and update your persisted data store.

> **`includeDeleted` defaults to `true`** — by default, API responses include records that have been deleted from NIPR. Pass `includeDeleted=false` if your system should only process active records. Be intentional: omitting this parameter means your system will receive and need to handle deletions.

### [Example 1: Daily License Updates](#example-1-daily-license-updates)

**Assumption**: The customer has already made the initial call to pull license data for each NPN and persisted it.

**Steps:**

1.  Call:
    
    ```bash
    GET /v2/licenses?updatedSince=yyyy-mm-dd
    ```
    
    -   With webhooks → use today's date
    -   Without webhooks → use today's date - 1
2.  Process paginated data and update the relevant NPNs.
3.  Repeat this process daily.

### [Example 2: Daily Appointment Updates](#example-2-daily-appointment-updates)

**Assumption**: The customer has already made the initial call to pull appointment data for each NPN and persisted it.

**Steps:**

1.  Call:
    
    ```bash
    GET /v2/appointments?updatedSince=yyyy-mm-dd
    ```
    
    -   With webhooks → use today's date
    -   Without webhooks → use today's date - 1
2.  Process paginated data and update the relevant NPNs.
3.  Repeat this process daily.

**Note**: Always increment the date provided (today or today-1). This ensures no missed updates.