Companies

Create or update companies in bulk (upsert)

Changed on

Upserts up to 50 companies under the caller's agency in one request. Each item follows the same field rules as POST /api/v1/companies, and must carry at least one match key: id, websiteUrl, or linkedinUrl.

Matching. id wins: when an item carries an id, it is authoritative and update-only — an unknown id fails the item (a company is never created with a caller-supplied id), and a supplied websiteUrl/linkedinUrl owned by a different company fails the item. Without an id, Atlas looks for an existing company owning the supplied linkedinUrl (the more reliable identifier, checked first) or websiteUrl. A match updates that company; no match creates one — use POST /api/v1/companies/batch instead when existing companies must be reported as failures rather than updated.

Update semantics. Only fields present on the item are written — an omitted field is left unchanged, null clears a nullable field, and custom attributes are replaced per attribute (as in PATCH /companies/{id}). websiteUrl / linkedinUrl act as match keys only: an update never adds or modifies the company’s identities. relationship defaults to none only when the item creates a company — omitted on an update it leaves the stored relationship unchanged; note that none companies are excluded from the default GET /api/v1/companies, so send client or target to have a newly created company appear there. An industry label matching the Atlas industry dictionary is stored in the dictionary’s canonical casing; any other label is stored exactly as sent — the rule is the same on create and update, since the caller cannot know up front which branch an item takes. (PATCH /companies/{id} is stricter: it rejects labels outside the dictionary.)

Items are processed independently and run a few at a time, so they do not necessarily complete in request order; results are always reported in request order via index. An item that fails — e.g. its websiteUrl and linkedinUrl resolve to two different existing companies, it references an unknown custom attribute, or an unexpected internal error occurs — is reported with status: "failed" and does not abort the remaining items. Internal errors carry a generic error message and are safe to retry only when the message says the item was not processed; when the failure happened after a company row was already persisted, the error says so and includes the created company id — do not retry that item as-is; verify the company and complete any missing fields via PATCH /api/v1/companies/{id} instead.

The response is always 200 with one result per input item (matched by index, the zero-based position in the request array) plus a summary of created/updated/failed counts. A request-level validation error (malformed item, more than 50 items, or the same company named by two items — see the request body) is rejected as a whole with 422 and writes nothing. Each successful item returns the company id only — read full details via GET /api/v1/companies/{id}.

post/api/v1/companies/batch/upsert

Request

Request body

Example request

{
  "companies": [
    {
      "name": "Acme Corp",
      "websiteUrl": "https://acme.com",
      "linkedinUrl": "https://linkedin.com/company/acme",
      "summary": "B2B SaaS",
      "size": "51-200",
      "industry": [
        "Software"
      ],
      "relationship": "client",
      "employeeCount": 150,
      "ticker": "AAPL",
      "location": {
        "name": "London, UK",
        "locality": "London",
        "region": "England",
        "metro": "new york, new york",
        "country": "United Kingdom",
        "streetAddress": "123 Baker Street",
        "addressLine2": "Suite 200",
        "postalCode": "NW1 6XE",
        "raw": "123 Baker Street, London NW1 6XE, United Kingdom",
        "latitude": 51.523767,
        "longitude": -0.158519
      },
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ]
}

Response

Batch processed — check each result item (and the summary) for per-item outcomes

status'ok' required

Example response

{
  "summary": {
    "total": 3,
    "created": 1,
    "updated": 1,
    "failed": 1
  }
}

Changes

    • info

      added the new undefined enum value to the request property //

    • info

      added the new undefined enum value to the request property //

    • info

      added the optional property to the response with the status