PlanDocket

Bulk Import

Business+

Import multiple records at once.

Required scopes: contacts participants
Access level: GET {scope}:read POST / PUT / PATCH / DELETE {scope}:write About access levels
The /contacts endpoint requires the "contacts" scope, the /participants endpoint requires the "participants" scope.

Endpoints

POST /api/v1/bulk-import/contacts

Import contacts

POST /api/v1/bulk-import/participants

Import participants

Request Schema

Parameter Type Required Description
records array Yes Array of records to import (max 1000)
field_mapping object No Object mapping source field names to target field names
mode string No Import mode: create (skip existing records, reason "exists"), upsert, or update (default: create). Unchanged participants are reported as skipped with reason "no_changes"
match_field string No Field to match existing records: email or customer_number (default: email)
skip_on_error boolean No Whether to skip records with errors and continue (default: true)
event_key string No Event key for participant import (required for participants)
create_contacts boolean No Whether to create contacts that do not exist during participant import (default: true; requires the contacts:write scope)

Response Schema

Field Type
total integer
created integer
updated integer
skipped integer
contacts_created integer
errors array
details array

Code Examples

curl -X POST "https://your-tenant.plandocket.com/api/v1/bulk-import/contacts" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "create",
    "match_field": "email",
    "records": [
        {
            "company_name": "Acme GmbH",
            "email": "info@acme.example",
            "first_name": "Max",
            "last_name": "Mustermann"
        }
    ]
}'
<?php
$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://your-tenant.plandocket.com';

$payload = [
    'mode' => 'create',
    'match_field' => 'email',
    'records' => [
        [
            'company_name' => 'Acme GmbH',
            'email' => 'info@acme.example',
            'first_name' => 'Max',
            'last_name' => 'Mustermann',
        ],
    ],
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $baseUrl . '/api/v1/bulk-import/contacts',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
print_r($data);
const apiKey = 'YOUR_API_KEY';
const baseUrl = 'https://your-tenant.plandocket.com';

const payload = {
    "mode": "create",
    "match_field": "email",
    "records": [
        {
            "company_name": "Acme GmbH",
            "email": "info@acme.example",
            "first_name": "Max",
            "last_name": "Mustermann"
        }
    ]
};

const response = await fetch(`${baseUrl}/api/v1/bulk-import/contacts`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(payload),
});

const data = await response.json();
console.log(data);
import requests

api_key = 'YOUR_API_KEY'
base_url = 'https://your-tenant.plandocket.com'

headers = {
    'Authorization': f'Bearer {api_key}',
}

payload = {
    'mode': 'create',
    'match_field': 'email',
    'records': [
        {
            'company_name': 'Acme GmbH',
            'email': 'info@acme.example',
            'first_name': 'Max',
            'last_name': 'Mustermann',
        },
    ],
}

response = requests.request('POST', f'{base_url}/api/v1/bulk-import/contacts', headers=headers, json=payload)
data = response.json()
print(data)

Sample Response

200 OK
{
    "data": {
        "total": 1,
        "created": 1,
        "updated": 1,
        "skipped": 1,
        "contacts_created": 1,
        "errors": [],
        "details": []
    }
}