---
title: "Prepare a contact request email"
method: POST
path: "/contact-requests/prepare"
tags: ["Contacts"]
---

# Prepare a contact request email

`POST /contact-requests/prepare`

## Request

- Base URL: `https://api.primitive.dev/v1`
- URL: `https://api.primitive.dev/v1/contact-requests/prepare`
- Auth: HTTP bearer

Builds a primitive.contact/1 request (the same email the Primitive CLI sends for `contacts request`) and returns the POST /send-mail call to make. Nothing is sent and no contact preference changes. A connected agent sends from its own address; other credentials name `from`.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `to` string, email, required: The address to contact.
  - `reason` string, required: Why you want to correspond, in one or two sentences.
  - `expires_in_seconds` integer
  - `from` string, email: Required unless the credential is a connected agent.

## Response `200`

Success

- object
  - `success` true, required
  - `data` object, required
    - `request` object, required: Identity of the prepared step. Keep interaction_id, step_id and expires_at to match a later acceptance.
      - `interaction_id` string
      - `step_id` string, uuid
      - `prev_step_id` string, uuid, nullable
      - `expires_at` string, date-time
    - `send` object, required: The exact request to make next, unchanged: method, path, headers (including Idempotency-Key) and JSON body.
      - `method` 'POST'
      - `path` string
      - `headers` object
      - `body` object

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key
- `403`: Authenticated caller lacks permission for the operation
- `429`: Rate limit exceeded. The `ratelimit-*` headers describe the limiter that rejected this request, with its own limit and window, not the API budget that successful responses report. A limiter that reports only a wait sends `Retry-After` alone.

## Changes

> 32 revisions in range; 1 not diffed.

- **2026-11-03** `bce409c97acb`: 124 warning
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `400`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `401`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `403`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `429`
  - …120 more
  - …this revision’s changelog is incomplete
- **2026-10-21** `0360ea8d4f3d`: 52 warning
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `400`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `401`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `403`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `429`
  - …48 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/primitive/apis/primitive-api/changes/contact-requests/prepare/post.md)

---

[API](https://skmtc.dev/primitive/apis/primitive-api.md) - [All operations](https://skmtc.dev/primitive/apis/primitive-api/llms.txt) - [OpenAPI document](https://skmtc.dev/primitive/apis/primitive-api/revisions/bce409c97acb?raw)
