---
title: "Create up to 100 contacts in one request"
method: POST
path: "/api/v1/contacts/batch"
tags: ["Records"]
---

# Create up to 100 contacts in one request

`POST /api/v1/contacts/batch`

## Request

- Base URL: `https://api.agendaforge.app`
- URL: `https://api.agendaforge.app/api/v1/contacts/batch`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Synchronous batch create. Each item behaves exactly like a single POST /api/v1/contacts request (same validation, same contact.added trigger). Items succeed or fail independently: the response pairs every input index with either the created contact or a typed error, so one duplicate email never fails the whole batch. For larger sets use POST /api/v1/imports/contacts.

## Headers

- `Idempotency-Key` string

## Request body

- BatchContactsRequest
  - `contacts` CreateContactRequest[], required
    - `type` string: speaker | sponsor | attendee | vendor | partner | exhibitor | other. Defaults to "attendee".
    - `firstName` string, required
    - `lastName` string, required
    - `email` string, email, required
    - `phone` string
    - `company` string
    - `jobTitle` string

## Response `200`

Per-item results in input order plus a summary. HTTP 200 even when some items fail; inspect results[].status.

- BatchContactsResponse
  - `results` object[], required: One entry per input item, in input order.
    - `index` integer, required: Position in the request array.
    - `status` 'created' | 'error', required
    - `contact` Contact: Emitted identically by webhook deliveries, trigger samples, and the create response.
      - `id` string
      - `type` string: speaker | sponsor | attendee | vendor | partner | exhibitor | other.
      - `firstName` string
      - `lastName` string
      - `email` string
      - `phone` string, nullable
      - `company` string, nullable
      - `jobTitle` string, nullable
      - `bio` string, nullable
      - `avatarUrl` string, nullable
      - `location` string, nullable
      - `website` string, nullable
      - `socialLinks` object, nullable: Map of platform to URL.
      - `expertiseAreas` string[]
      - `tags` string[]
      - `customFields` object, nullable: Organization-defined custom fields.
      - `source` string, nullable
      - `status` string
      - `rating` number, nullable
      - `createdAt` string: ISO-8601 UTC timestamp.
      - `events` ContactEventRef[]
        - `eventId` string
        - `eventName` string
        - `eventNumber` number, nullable
        - `role` string
        - `status` string
    - `error` object: Present when status is "error"; same code vocabulary as top-level errors.
      - `code` string, required
      - `message` string, required
  - `summary` object, required
    - `total` integer, required
    - `created` integer, required
    - `failed` integer, required

## Other responses

- `400`: A required field is missing or invalid, an unknown event was supplied, or a referenced record is not owned by the key's organization.
- `401`: The API key is missing, malformed, invalid, expired, or revoked.
- `403`: The API key is valid but does not include the public_api scope. Create a key with the public_api scope in Settings > API Tokens.
- `404`: No such endpoint under /api/v1. The message lists the valid endpoints.
- `409`: The Idempotency-Key was already used on a different endpoint within the 24 hour retention window.
- `429`: The fixed window for this API key (120 requests per minute) or IP (30 per minute, unauthenticated) is exhausted. Wait Retry-After seconds and retry.
- `500`: An unexpected server failure. The body still follows the JSON error contract; retry with exponential backoff.
- `default`: Any other failure, including 404 NOT_FOUND for an unknown path and transient 5xx errors. Always the same JSON error contract.

---

[API](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api.md) · [All operations](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api/revisions/b8956ce1e5f3?raw)
