todos:upsert
Description: Create a todo or update a single todo by ID.
Todos are task items that can be assigned to people and attached to activities (or other taskable entities). Use this message type to create new todos or update existing ones.
Request Schema
{
"payload": {
"id": 1, // When set, update existing record, else create new record
"type": "todos:upsert",
"title": "Complete onboarding checklist",
"description": "Review all required documents and sign the agreements",
"due_on": "2026-04-20",
"taskable": {
"type": "activity",
"id": 456
},
"person_id": 789
},
"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. |
title | String | Yes | null | 255 | Todo title. Required. |
description | String | No | null | - | Todo description (plain text) |
due_on | Date | No | null | - | Due date for the todo. Format: YYYY-MM-DD (ISO 8601) |
taskable | Object | Yes | null | - | Parent entity to attach the todo to. Required. Currently only activity type is supported. See Taskable fields
|
person_id | Integer | No | null | - | Arkipel ID of the person to assign this todo to |
Taskable Fields
The taskable object specifies the parent entity to which the todo belongs:
| Field | Type | Required | Description |
|---|---|---|---|
type | String | Yes | Taskable type. Currently only "activity" is supported |
id | Integer | Yes | Arkipel ID of the taskable entity (e.g., activity ID) |
Note: Todos are created/updated via activities (taskables). The activity serves as the container or context for the todo.
Real Life Examples
Creating a Todo on an Existing Activity
{
"type": "todos:upsert",
"title": "Review quarterly report",
"description": "Check all financial figures and prepare summary",
"due_on": "2026-04-25",
"taskable": {
"type": "activity",
"id": 12345
}
}
Creating a Todo with an Assignee
{
"type": "todos:upsert",
"title": "Call client for follow-up",
"description": "Discuss project timeline and next steps",
"due_on": "2026-04-20",
"taskable": {
"type": "activity",
"id": 12345
},
"person_id": 987
}
Updating an Existing Todo
{
"type": "todos:upsert",
"id": 456,
"title": "Review quarterly report - UPDATED",
"description": "Additional notes added",
"due_on": "2026-04-30",
"person_id": 789
}
Response Schema
{
"source_public_key": "community_public_key",
"source_site": {
"protocol": "https",
"fqdn": "arkipel.localhost:3000"
},
"created_at": "2025-11-13T20:52:49Z",
"signature": "8b6392d5550605bd6ccddf9c21ebec470de4b44e4b4deb746076e37ab61c5346e07e7c7c7cebb5bbee41cdd92a476bcd3f02373d146ec165b31c31fc31c9ce0d",
"payload": {
"message_id": "6916452112f746b2b4cf48c1",
"type": "todos:upsert"
}
}
Response Attributes
-
payload.message_id- String - The unique identifier for the async processing message. Use this to check the processing status. -
payload.type- String - Always “todos:upsert”
Asynchronous Processing
This is an async mutation. The response returns a message_id which you poll using arkipel_messages:query to retrieve the result. See Asynchronous Processing for complete documentation on polling strategies and status values.
Error Handling
Common error scenarios:
- Record not found: Activity (taskable) does not exist or does not belong to the account
- Validation failed: Invalid payload, missing required fields, or data validation error
- Authorization failed: Insufficient permissions to create/update todos
- General error: Unexpected processing error
Related Message Types
-
todo:query- Retrieve a single todo by ID -
todos:query- Retrieve a list of todos -
todo:close- Close (mark as completed) a todo -
todo:reopen- Reopen (mark as not completed) a todo