people:upsert
Description: Create a person or update a single person by ID.
Request Schema
{
"payload": {
"id": 1, // When set, update existing record, else create new record
"type": "people:upsert",
"first_name": "Jane",
"last_name": "Doe",
"import_id": "JD0001",
"category": { "id": 1 }, // Existing person category, see payload specs for the appropriate category: person_categories:query
"locale": "fr",
"gender": "woman",
"dob": "1970-12-30",
"data_consent": "accepted",
"accepts_marketing": true,
"note": "Lorem Ipsum\ndolor sit amet.",
"forms": [
{ "id": 1, "data": { "key1": "value1", ... } } // See form:fill, `subject` key not required
],
"contact_informations": [
{
"label": "Home",
"type": "PhoneNumber",
"info": "123 1234",
"main": true
}, // New record
{
"id": 1,
"type": "Email",
"label": "Office",
"info": "info@example.com",
"main": false
} // Existing record
],
"addresses": [
{
"name": "Home", // Address label
"street1": "259 Wellington St. W", // Number and street
"street2": "Appt 1", // Appartment number, PO Box, etc...
"city": "Toronto", // City name
"zip": "M5V 3P9", // Postal code
"region_code": "ON", // Province/State code - https://en.wikipedia.org/wiki/ISO_3166-2
"country_code": "CA", // Country code - https://en.wikipedia.org/wiki/ISO_3166-2
"main": true // Main address, only 1 per person
}, // New record
{
"id": 1,
"name": "Office",
"main": false
} // Existing record, same attributes as example above
]
},
"signature": "payload_ed25519_hex_signature",
"source_public_key": "your_client_public_key"
}
Request Attributes
Field Constraints
| Field | Type | Required | Default | Max Length | Constraints |
|---|---|---|---|---|---|
id | Integer | No | null | - | Arkipel ID. When set, updates existing record. When omitted, creates new record. |
first_name | String | Conditional | null | 255 | Required if last_name is blank. Whitespace is trimmed. |
last_name | String | Conditional | null | 255 | Required if first_name is blank. Whitespace is trimmed. |
import_id | String | Yes | Auto-generated | 255 |
Your external system ID for this person. Unique per account. Auto-generated if not provided. Use your system’s format (e.g., crm_12345). |
category | Object | No | null | - |
{ "id": 1 }. See person_categories:query
|
locale | Enum | No | null | - | Values: fr, en
|
gender | Enum | No | unknown | - | Values: unknown, confidential, man, woman, other
|
dob | Date | No | null | - | Format: YYYY-MM-DD (ISO 8601) |
data_consent | Enum | No | unknown | - | Values: unknown, accepted, rejected
|
accepts_marketing | Boolean | No | false | - | Consent to receive electronic communications |
reason | String | Conditional | null | 255 | Required when status is inactive
|
status | Enum | No | active | - | Values: wizard, active, inactive
|
note | Text | No | null | - | Free-form text about the person |
contact_informations | Array | No | [] | - | See ContactInformation fields below |
addresses | Array | No | [] | - | See Address fields below |
forms | Array | No | [] | - | Form submissions. See form:fill
|
Required field rule: At least one of first_name or last_name must be provided.
Special Field: import_id
The import_id field is your integration’s identifier for this person. Use it to link Arkipel records with your external system.
Characteristics:
- Required but auto-generated if not provided
- Must be unique per account (case-insensitive)
-
Your external system ID format is recommended (e.g.,
crm_12345,legacy_98765,myapp_user_456) - Used for idempotent operations and duplicate prevention
- Auto-generated format: 6 characters from
234679ACDEFGHJKMNPRTVWXYZ
Example usage:
{
"import_id": "crm_12345",
"first_name": "Jane",
"last_name": "Doe"
}
ContactInformation Fields
Each contact information object in the contact_informations array:
| Field | Type | Required | Max Length | Description |
|---|---|---|---|---|
id | Integer | No | - | Arkipel ID. When set, updates existing record. When omitted, creates new record. |
type | String | No | 255 | Contact type: Email, PhoneNumber, CellNumber, Website, FaxNumber
|
info | String | Yes | 255 | The contact value (email address, phone number, URL, etc.) |
label | String | No | 255 | Label for this contact (e.g., “Home”, “Office”) |
main | Boolean | No | - | Is this the primary contact? Default: false
|
Email validation: info must be a valid email format when type is Email.
Phone sanitization: Phone numbers are stored as digits only (non-digits are stripped).
Address Fields
Each address object in the addresses array:
| Field | Type | Required | Max Length | Description |
|---|---|---|---|---|
id | Integer | No | - | Arkipel ID. When set, updates existing record. When omitted, creates new record. |
name | String | No | 255 | Address label (e.g., “Home”, “Office”) |
street1 | String | No | 255 | Street address line 1 |
street2 | String | No | 255 | Street address line 2 (apartment, suite, etc.) |
city | String | No | 255 | City name |
zip | String | No | 255 | Postal/ZIP code. Auto-formatted for Canadian addresses. |
region_code | String | No | 255 | Province/State code (ISO 3166-2) |
country_code | String | Yes | 255 | Country code (ISO 3166-2). Required. |
main | Boolean | No | - | Is this the primary address? Default: false
|
kind_home | Boolean | No | - | Is this a home address? |
kind_business | Boolean | No | - | Is this a business address? |
kind_billing | Boolean | No | - | Is this a billing address? |
kind_hub | Boolean | No | - | Is this a hub/distribution address? |
kind_shipping | Boolean | No | - | Is this a shipping address? |
latitude | Float | No | - | GPS latitude |
longitude | Float | No | - | GPS longitude |
Address kind validation: At least one of kind_home, kind_business, kind_billing, kind_hub, or kind_shipping must be true.
Response Schema
{
"source_public_key": "community_public_key",
"source_site": {
"protocol": "http",
"fqdn": "arkipel.localhost:3000"
},
"created_at": "2025-11-13T20:52:49Z",
"signature": "8b6392d5550605bd6ccddf9c21ebec470de4b44e4b4deb746076e37ab61c5346e07e7c7c7cebb5bbee41cdd92a476bcd3f02373d146ec165b31c31fc31c9ce0d",
"payload": {
"message_id": "6916452112f746b2b4cf48c1",
"type": "people:upsert"
}
}