> For the complete documentation index, see [llms.txt](https://support.sayprimer.com/primer/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://support.sayprimer.com/primer/learn-more/push-people-and-companies-to-primer-via-api-beta.md).

# Push People and Companies to Primer via API (Beta)

Send people or company records directly to Primer through an HTTP API.

Primer’s API ingestion beta lets you keep first-party data from your CRM, data warehouse, or another internal system in sync with Primer. Once imported, these records become an audience-building dataset in Primer.

> **Beta availability**
>
> API ingestion is currently available as a beta feature. Contact your Primer representative or <support@sayprimer.com> to request access and receive your API credentials.

### How API ingestion works

You can send two types of records to Primer:

* **People**, such as leads, contacts, or customers
* **Companies**, such as accounts or target organizations

Every record must include a stable, unique identifier. You choose this identifier—it might be a CRM record ID, email address, company domain, or another value that does not change over time.

By default, your data appears in an imported dataset named `from_api`. You can then use the dataset when building audiences in Primer.

API ingestion is incremental: send records whenever they are created or changed in your source system. Records that are not included in a request remain in the dataset.

For large, one-time file imports, contact your Primer representative to discuss an S3-based data transfer instead.

### Before you begin

Your Primer representative will provide:

* The production API base URL: `https://primer-platform.api.sayprimer.com`
* An API key
* A custom dataset name, if needed
* A custom ID field, if your records do not use `id`

Include your API key in the `Authorization` header of every request:

```
Authorization: Bearer <your API key>
```

Keep your API key private. Do not include it in client-side applications, public repositories, or shared documentation.

### Endpoints

| Record type | Method | Endpoint                                                                                                                   |
| ----------- | ------ | -------------------------------------------------------------------------------------------------------------------------- |
| People      | `POST` | [`https://primer-platfrom.api.sayprimer.com/ingest/people`](https://primer-platfrom.api.sayprimer.com/ingest/people)       |
| Companies   | `POS`  | [`https://primer-platform.api.sayprimer.com/ingest/companies`](https://primer-platfrom.api.sayprimer.com/ingest/companies) |

Requests must use `Content-Type: application/json`.

### Optional query parameters

| Parameter  | Default    | Description                                                                                                 |
| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
| `dataset`  | `from_api` | The name of the imported dataset in Primer. The name cannot contain `-batch-`.                              |
| `id_field` | `id`       | The JSON field containing each record’s stable ID. Every record must have a non-empty value for this field. |

For example:

```
https://primer-platform.api.sayprimer.com/ingest/companies?dataset=my-accounts
```

### Supported people fields

Send people records to `POST /ingest/people`.

| Field            | JSON key         |
| ---------------- | ---------------- |
| Record ID        | `id`             |
| First name       | `first_name`     |
| Last name        | `last_name`      |
| Email            | `email`          |
| LinkedIn profile | `linkedin_url`   |
| Company domain   | `company_domain` |
| Company name     | `company_name`   |
| Country          | `country`        |
| State or region  | `state`          |
| City             | `city`           |

For the best matching results, include an email address and person LinkedIn URL whenever one is available.

### Supported company fields

Send company records to `POST /ingest/companies`.

| Field                 | JSON key         |
| --------------------- | ---------------- |
| Record ID             | `id`             |
| Company name          | `company_name`   |
| Company domain        | `company_domain` |
| LinkedIn company page | `linkedin_url`   |
| Country               | `country`        |
| State or region       | `state`          |
| City                  | `city`           |

For the best matching results, include `company_domain`, `linkedin_url`, or both. Companies with neither value may not match successfully.

### Send a person to Primer

The following example sends one person record:

```
curl -X POST "https://primer-platform.api.sayprimer.com/ingest/people" \
  -H "Authorization: Bearer <your API key>" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "contact-123",
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com",
    "linkedin_url": "https://linkedin.com/in/ada",
    "company_domain": "example.com",
    "company_name": "Example Inc",
    "country": "United States",
    "state": "California",
    "city": "San Francisco"
  }'
```

A successful request returns:

```
{
  "accepted": 1
}
```

with an HTTP status of `202 Accepted`.

### Send multiple records

You can send a JSON array to import multiple records in one request:

```
curl -X POST "https://primer-platform.api.sayprimer.com/ingest/people" \
  -H "Authorization: Bearer <your API key>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "id": "contact-123",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "email": "ada@example.com",
      "company_domain": "example.com",
      "company_name": "Example Inc"
    },
    {
      "id": "contact-456",
      "first_name": "Bob",
      "last_name": "Smith",
      "email": "bob@example.com",
      "company_domain": "acme.com",
      "company_name": "Acme Corp"
    }
  ]'
```

For batch requests, Primer also accepts an object containing a `records` array:

```
{
  "records": [
    {
      "id": "company-10",
      "company_name": "Acme Corp",
      "company_domain": "acme.com"
    },
    {
      "id": "company-20",
      "company_name": "Beta LLC",
      "company_domain": "beta.io"
    }
  ]
}
```

### Updating existing records

Primer uses the stable ID to determine whether a request creates a record or updates an existing one.

Each request affects only the records included in that request. Other records in the dataset are preserved.

> **Important:** Send the complete set of fields you want Primer to retain for each record. When updating an existing ID, a field that is omitted or sent with an empty value is cleared in Primer.

For example, if a record currently has an email address and your next request for that ID omits `email`, Primer clears the stored email value.

### When your data will appear

API requests are processed asynchronously. After receiving a successful `202 Accepted` response, records typically appear in Primer within **15–60 minutes**.

Processing time depends on the number of records submitted and the timing of Primer’s next import cycle.

You can review imported datasets on the [CSV Imports page in Primer](https://my.sayprimer.com/connections?tab=CSV%20Imports).

### Responses and troubleshooting

| Status | Meaning                                                                                                                       |
| ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| `202`  | The request was accepted. The response includes `{"accepted": N}`, where `N` is the number of accepted records.               |
| `400`  | The request body is invalid, a record is missing its ID, the batch is empty, or the `dataset` or `id_field` value is invalid. |
| `401`  | The API credentials could not be authenticated. Contact Primer Support if the problem continues.                              |
| `403`  | API ingestion is not enabled for your Primer organization. Contact Primer Support.                                            |
| `413`  | The request exceeds the maximum record count or body size. Divide the data into smaller requests.                             |
| `429`  | The request limit was exceeded. Wait and retry using exponential backoff.                                                     |
| `503`  | Primer encountered a temporary issue. Wait a few minutes and retry.                                                           |

### Usage limits

The beta currently supports:

* Up to **600 requests per minute** for each Primer organization
* Up to **50,000 records per request**
* A maximum request-body size of **10 MB**

If a batch exceeds either request limit, divide it into smaller batches before sending it again.

### Recommended testing process

Before enabling an ongoing integration:

1. Send one test record with a unique ID.
2. Confirm that the API returns `202 Accepted` and `"accepted": 1`.
3. Wait 15–60 minutes for the record to appear in Primer.
4. Find the dataset on the [CSV Imports page](https://my.sayprimer.com/connections?tab=CSV%20Imports).
5. Send another request using the same ID and updated field values.
6. Confirm that the existing record was updated.
7. Verify that any fields you intended to retain were not omitted from the update.

### Beta considerations

Because this feature is in beta:

* API behavior, limits, and supported fields may change.
* Processing times may vary.
* Primer may request feedback about your integration and use case.
* Beta participation does not guarantee that the feature will become generally available in its current form.
* Primer does not recommend using the beta as the sole copy of business-critical data.

### Next steps

To request access to API ingestion, contact your Primer representative or email <support@sayprimer.com>.

Primer will provide your API credentials and help confirm the appropriate dataset and record-ID configuration for your integration.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://support.sayprimer.com/primer/learn-more/push-people-and-companies-to-primer-via-api-beta.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
