Global Request & Response Schemas
This page defines the common structures used across all Arkipel API messages.
Overview
Every API interaction follows a consistent message envelope pattern. Understanding these structures helps you:
- Parse responses correctly
- Handle authentication requirements
- Implement pagination
- Track asynchronous operations
Request Envelope
All requests to the API must include these top-level fields:
{
"payload": {
"type": "message:type",
"...": "message-specific fields"
},
"timestamp": "2026-01-21T10:30:00Z",
"signature": "hex_encoded_ed25519_signature",
"source_public_key": "zbase32_encoded_public_key"
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
payload | Object | Yes | Contains the message type and data |
payload.type | String | Yes | Message type (e.g., people:query, organizations:upsert) |
timestamp | String | Token auth | ISO 8601 UTC timestamp (YYYY-MM-DDTHH:MM:SSZ) |
signature | String | Keypair auth | Ed25519 signature of the payload (hex encoded) |
source_public_key | String | Keypair auth | Your public key in ZBase32 format (52 characters) |
Authentication Methods
API Token Authentication:
{
"payload": { "type": "ping" },
"timestamp": "2026-01-21T10:30:00Z"
}
Include Authorization: Bearer YOUR_TOKEN header.
Keypair Authentication:
{
"payload": { "type": "ping" },
"signature": "a1b2c3d4e5f6...",
"source_public_key": "bwyexzko74pnnjn741936fnaujxyhib9rpx8rggtejwnc3cz6ans"
}
Response Envelope
All API responses follow this consistent structure:
{
"source_public_key": "community_public_key",
"source_site": {
"protocol": "https",
"fqdn": "arkipel.example.com"
},
"created_at": "2025-11-13T20:52:49Z",
"signature": "hex_encoded_ed25519_signature",
"payload": {
"type": "message:type",
"...": "response data"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
source_public_key | String | The community’s public key |
source_site.protocol | String |
"http" or "https"
|
source_site.fqdn | String | Fully qualified domain name |
created_at | String | ISO 8601 timestamp when message was processed |
signature | String | Community’s Ed25519 signature (hex encoded) |
payload | Object | Response data specific to the message type |
payload.type | String | Same message type from your request |
Verification
When using keypair authentication, you can verify the response signature:
- Extract
payloadfrom response - Verify
signatureusing the community’s public key - This ensures the response is authentic and unmodified
Synchronous Response (Queries)
Query operations return data immediately:
{
"source_public_key": "community_key",
"source_site": { "protocol": "https", "fqdn": "..." },
"created_at": "2025-11-13T20:52:49Z",
"signature": "...",
"payload": {
"type": "people:query",
"q": {
"per_page": 20,
"page": 1,
"total": 150
},
"resources": [
{ "id": 1, "first_name": "John", "last_name": "Doe" }
]
}
}
Asynchronous Response (Mutations)
Mutation operations return a message_id for status tracking:
{
"source_public_key": "community_key",
"source_site": { "protocol": "https", "fqdn": "..." },
"created_at": "2025-11-13T20:52:49Z",
"signature": "...",
"payload": {
"type": "people:upsert",
"message_id": "6916452112f746b2b4cf48c1"
}
}
Async Tracking
Use the message_id to check operation status:
Request:
{
"payload": {
"type": "arkipel_messages:query",
"message_id": "6916452112f746b2b4cf48c1"
}
}
Response:
{
"payload": {
"type": "arkipel_messages:query",
"message_id": "6916452112f746b2b4cf48c1",
"status": "persisted",
"resource": { "id": 123, "first_name": "Jane", ... }
}
}
Async Status Values
| Status | Meaning |
|---|---|
pending | Message received, waiting to be processed |
processing | Currently being processed |
persisted | Successfully completed, resource available |
failed | Processing failed, check error field |
rejected | Rejected by validation or policy |
Pagination Schema
List queries support pagination through the q parameter:
Request
{
"payload": {
"type": "people:query",
"q": {
"page": 1,
"per_page": 20
}
}
}
Pagination Parameters
| Parameter | Type | Default | Maximum | Description |
|---|---|---|---|---|
page | Integer | 1 | - | Page number (starts at 1) |
per_page | Integer | 20 | 100 | Records per page |
Response
{
"payload": {
"type": "people:query",
"q": {
"per_page": 20,
"page": 1,
"total": 150
},
"resources": [ ... ]
}
}
Pagination Response Fields
| Field | Type | Description |
|---|---|---|
payload.q.per_page | Integer | Records per page (as requested) |
payload.q.page | Integer | Current page number |
payload.q.total | Integer | Total number of records available |
Calculating Pages
const totalPages = Math.ceil(total / per_page);
const hasNextPage = page < totalPages;
const hasPreviousPage = page > 1;
Error Response Schema
Error responses maintain the same envelope structure:
{
"source_public_key": "community_key",
"source_site": { "protocol": "https", "fqdn": "..." },
"created_at": "2025-11-13T20:52:49Z",
"signature": "...",
"payload": {
"type": "arkipel_messages:query",
"message_id": "abc123",
"status": "failed",
"error": {
"code": "VALIDATION_FAILED",
"message": "Invalid attribute: email format is invalid",
"details": {
"attribute": "email",
"value": "invalid-email"
}
}
}
}
Error Response Fields
| Field | Type | Description |
|---|---|---|
payload.status | String |
"failed" or "rejected"
|
payload.error.code | String | Machine-readable error code |
payload.error.message | String | Human-readable description |
payload.error.details | Object | Additional context (field names, values, etc.) |
See Error Codes for complete list of error codes and handling strategies.
Common Patterns
Nested Resources
Many messages support nested creation. The envelope structure remains the same, but payload contains nested objects:
{
"payload": {
"type": "households:upsert",
"household": {
"name": "Smith Family",
"people": [
{ "first_name": "John", "last_name": "Smith" }
],
"addresses": [
{ "country_code": "CA", "street1": "123 Main St" }
]
}
}
}
Partial Updates
Upsert operations support partial updates. Include only fields you want to change:
{
"payload": {
"type": "people:upsert",
"id": 123,
"note": "Updated note only"
}
}
Omitted fields retain their existing values.
Related Documentation
- Error Handling - HTTP status codes and error messages
- Asynchronous Processing - Detailed async flow and polling strategies
- API Connection - Authentication and setup
Return to API Specifications