> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.partnerpage.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.partnerpage.io/_mcp/server.

# Create a new partner contact request

POST https://v1.api.partnerpage.io/api/directory/private/v1alpha/directories/{directoryId}/entries/partners/{entryId}/contact-requests/
Content-Type: application/json

Create a contact request for a partner in one of your own directories from your own server. Authenticate with your API token (`Authorization: Token <your-api-token>`); the token's organization must own the directory. CAPTCHA is not required: the token is the trust signal. The contact form on the public directory website is a separate flow for anonymous visitors; it requires a valid `captcha` and an API token does not replace it there.

Before submitting, read the directory's contact request form (`GET /api/directory/public/v1alpha/directories/{directoryId}/forms/contact-request/`) for the field IDs, internal labels, types and which fields are required. Send one answer per field in `form.answers`, identified by `fieldId` or `internalLabel`. First name, last name, email and company name are always required; the directory's form can require more. Property names are accepted in camelCase (as in the examples) or snake\_case (as in the schema).

`utmQueryParams` stores attribution data with the request. `routingSource` is a free-text label of up to 100 characters that records where your integration routed the request from (for example the partner pool it picked from); it is returned wherever the request is read back and can be filtered and reported on.

A company website without a scheme (`acme.com`) is stored with `https://`. One that is not an http(s) web address (for example an email address) is dropped, with its answer cleared, and the request is still created without it instead of answering 400.

The directory must have contact requests enabled and the partner entry must belong to the directory in the path. Limited to 50 requests per hour per user.

Reference: https://docs.partnerpage.io/api-reference/contact-request/create-a-new-partner-contact-request

## Authentication

- `Authorization` header (required) (prefixed with ` Token   `) — Your API key, sent as `Authorization: Token <your API key>`

## Request

### Path parameters

- `directoryId` (string, required) — ID of the directory containing the partner entry
- `entryId` (string, required) — ID of the partner entry to create a contact request for

### Body (application/json)

This endpoint expects a PartnerContactRequestCreateRequest.

- `form` (PartnerContactRequestCreateFormRequest, required)
- `utmQueryParams` (map from string to any, optional) — UTM attribution to store with the request, for example `{"utmSource": "api", "utmMedium": "server-to-server"}`.
- `routingSource` (string, optional, nullable) — Where your integration routed the request from, for example the partner pool it picked the partner from.

## Response

### 201

Partner contact request created successfully.

- `id` (string, required)
- `answers` (list of SubmittedAnswer, required)
- `created` (string, required, nullable)
- `routingSource` (string, required, nullable)
- `utmQueryParams` (any, optional, nullable)

## Errors

### 400 Bad Request Error

Invalid submission: a required field is missing, an answer does not match its field, a field ID or internal label is unknown, the email domain is not accepted as a business email (when the directory requires business emails), or the routing source is longer than 100 characters. The body names the failing answer or field.

- `any`

### 401 Unauthorized Error

Missing or invalid API token (CAPTCHA is never required)

- `any`

### 403 Forbidden Error

Your API token's organization does not own this directory, contact requests are disabled for it, or the directory does not exist

- `any`

### 404 Not Found Error

Partner entry not found in this directory

- `any`

### 429 Too Many Requests Error

Rate limit exceeded (50 requests per hour per user)

- `any`

### 500 Internal Server Error

Unexpected error; the body carries the error message

- `any`

## Types

### PartnerContactRequestCreateFormRequest

- `answers` (list of SubmittedAnswerWriterRequest, required) — One answer per field of the directory's contact request form.

### SubmittedAnswer

- `field` (any, required)
- `answer` (any, required, nullable)
- `otherText` (string, optional, nullable)

### SubmittedAnswerWriterRequest

One submitted form answer.

- `answer` (any, required, nullable) — The submitted value. A string for text, email, URL and phone fields; the shape of option, date and other custom fields follows the field definition returned by the form endpoint.
- `fieldId` (string, optional) — ID of the form field this answer belongs to. Identify every answer by `fieldId` or by `internalLabel`.
- `internalLabel` (string, optional) — Internal label of the form field, for example `partnerpage-email`. Resolved within the directory's form.
- `otherText` (string, optional) — Free text entered for an option field's "Other" choice.

## Examples

### Field IDs and internal labels (application/json)

**Request**

```json
{
  "form": {
    "answers": [
      {
        "answer": null,
        "fieldId": "0165c5e6-e562-4ad9-adce-efc9844a95fc"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-last_name"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-email"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-company_name"
      }
    ]
  },
  "utmQueryParams": {
    "utmMedium": "server-to-server",
    "utmSource": "api"
  },
  "routingSource": "AMER, Commercial, 101-750 employees",
  "holdReason": null
}
```

**Response**

```json
{
  "id": "219a7d94-b934-4ccf-880f-d24b55e7e03e",
  "answers": [],
  "created": "2024-08-23T13:40:00+00:00",
  "routingSource": "AMER, Commercial, 101-750 employees",
  "utmQueryParams": {},
  "holdReason": null
}
```

**SDK Code**

```python Field IDs and internal labels (application/json)
import requests

url = "https://v1.api.partnerpage.io/api/directory/private/v1alpha/directories/:directoryId/entries/partners/:entryId/contact-requests/"

payload = {
    "form": { "answers": [
            {
                "answer": None,
                "fieldId": "0165c5e6-e562-4ad9-adce-efc9844a95fc"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-last_name"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-email"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-company_name"
            }
        ] },
    "utmQueryParams": {
        "utmMedium": "server-to-server",
        "utmSource": "api"
    },
    "routingSource": "AMER, Commercial, 101-750 employees",
    "holdReason": None
}
headers = {
    "Authorization": "Token  <apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Field IDs and internal labels (application/json)
const url = 'https://v1.api.partnerpage.io/api/directory/private/v1alpha/directories/:directoryId/entries/partners/:entryId/contact-requests/';
const options = {
  method: 'POST',
  headers: {Authorization: 'Token  <apiKey>', 'Content-Type': 'application/json'},
  body: '{"form":{"answers":[{"answer":null,"fieldId":"0165c5e6-e562-4ad9-adce-efc9844a95fc"},{"answer":null,"internalLabel":"partnerpage-last_name"},{"answer":null,"internalLabel":"partnerpage-email"},{"answer":null,"internalLabel":"partnerpage-company_name"}]},"utmQueryParams":{"utmMedium":"server-to-server","utmSource":"api"},"routingSource":"AMER, Commercial, 101-750 employees","holdReason":null}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

### Internal labels only (application/json)

**Request**

```json
{
  "form": {
    "answers": [
      {
        "answer": null,
        "internalLabel": "partnerpage-first_name"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-last_name"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-email"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-company_name"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-company_website"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-phone"
      },
      {
        "answer": null,
        "internalLabel": "partnerpage-comments"
      }
    ]
  }
}
```

**Response**

```json
{
  "id": "219a7d94-b934-4ccf-880f-d24b55e7e03e",
  "answers": [],
  "created": "2024-08-23T13:40:00+00:00",
  "routingSource": "AMER, Commercial, 101-750 employees",
  "utmQueryParams": {},
  "holdReason": null
}
```

**SDK Code**

```python Internal labels only (application/json)
import requests

url = "https://v1.api.partnerpage.io/api/directory/private/v1alpha/directories/:directoryId/entries/partners/:entryId/contact-requests/"

payload = { "form": { "answers": [
            {
                "answer": None,
                "internalLabel": "partnerpage-first_name"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-last_name"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-email"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-company_name"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-company_website"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-phone"
            },
            {
                "answer": None,
                "internalLabel": "partnerpage-comments"
            }
        ] } }
headers = {
    "Authorization": "Token  <apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Internal labels only (application/json)
const url = 'https://v1.api.partnerpage.io/api/directory/private/v1alpha/directories/:directoryId/entries/partners/:entryId/contact-requests/';
const options = {
  method: 'POST',
  headers: {Authorization: 'Token  <apiKey>', 'Content-Type': 'application/json'},
  body: '{"form":{"answers":[{"answer":null,"internalLabel":"partnerpage-first_name"},{"answer":null,"internalLabel":"partnerpage-last_name"},{"answer":null,"internalLabel":"partnerpage-email"},{"answer":null,"internalLabel":"partnerpage-company_name"},{"answer":null,"internalLabel":"partnerpage-company_website"},{"answer":null,"internalLabel":"partnerpage-phone"},{"answer":null,"internalLabel":"partnerpage-comments"}]}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```