Basecamp · Schema
Basecamp Webhook Payload
Represents the JSON payload delivered by Basecamp to a registered webhook endpoint when a subscribed event occurs within a project. Every payload includes a unique event ID, the event kind, a timestamp, the full recording object that triggered the event, the person who triggered it, and optional event-specific details.
CollaborationProject ManagementRESTSaaSTeam Communication
Properties
| Name | Type | Description |
|---|---|---|
| id | integer | Unique identifier for this webhook event delivery |
| kind | string | Event type descriptor identifying the resource type and action, formatted as {resource}_{action} (e.g., message_created, todo_completed, comment_updated) |
| created_at | string | ISO 8601 UTC timestamp when the triggering event occurred in Basecamp |
| recording | object | Full JSON representation of the Basecamp resource that triggered the event |
| creator | object | The Basecamp user whose action triggered the event |
| details | object | Event-specific contextual metadata. For copy and move events includes a copy object with the duplicated item reference. Contents vary by event kind. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/basecamp/bc3-api/schemas/basecamp/webhook-payload.json",
"title": "Basecamp Webhook Payload",
"description": "Represents the JSON payload delivered by Basecamp to a registered webhook endpoint when a subscribed event occurs within a project. Every payload includes a unique event ID, the event kind, a timestamp, the full recording object that triggered the event, the person who triggered it, and optional event-specific details.",
"type": "object",
"required": ["id", "kind", "created_at", "recording", "creator"],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier for this webhook event delivery"
},
"kind": {
"type": "string",
"description": "Event type descriptor identifying the resource type and action, formatted as {resource}_{action} (e.g., message_created, todo_completed, comment_updated)",
"enum": [
"message_created",
"message_updated",
"message_archived",
"message_trashed",
"message_subscribers_changed",
"message_publicized",
"todo_created",
"todo_updated",
"todo_completed",
"todo_uncompleted",
"todo_archived",
"todo_trashed",
"todo_subscribers_changed",
"todolist_created",
"todolist_updated",
"todolist_archived",
"todolist_trashed",
"document_created",
"document_updated",
"document_archived",
"document_trashed",
"comment_created",
"comment_updated",
"comment_trashed",
"card_created",
"card_updated",
"card_archived",
"card_trashed",
"schedule_entry_created",
"schedule_entry_updated",
"schedule_entry_archived",
"schedule_entry_trashed",
"upload_created",
"upload_updated",
"upload_archived",
"upload_trashed",
"question_answer_created",
"question_answer_updated",
"question_paused",
"question_resumed",
"inbox_forward_created",
"client_forward_created",
"client_correspondence_created"
]
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp when the triggering event occurred in Basecamp"
},
"recording": {
"$ref": "#/$defs/Recording",
"description": "Full JSON representation of the Basecamp resource that triggered the event"
},
"creator": {
"$ref": "#/$defs/Person",
"description": "The Basecamp user whose action triggered the event"
},
"details": {
"type": "object",
"description": "Event-specific contextual metadata. For copy and move events includes a copy object with the duplicated item reference. Contents vary by event kind.",
"additionalProperties": true,
"properties": {
"copy": {
"$ref": "#/$defs/Recording",
"description": "Reference to the original recording when this event was triggered by a copy or move operation"
}
}
}
},
"$defs": {
"Person": {
"type": "object",
"description": "A Basecamp user profile reference included in webhook payloads",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier for the person"
},
"attachable_sgid": {
"type": "string",
"description": "Signed global ID used to reference this person as an attachment"
},
"name": {
"type": "string",
"description": "Full display name of the person"
},
"email_address": {
"type": "string",
"format": "email",
"description": "Primary email address of the person"
},
"personable_type": {
"type": "string",
"description": "Personable type indicating user role",
"enum": ["User", "Client"]
},
"title": {
"type": "string",
"description": "Job title of the person"
},
"bio": {
"type": "string",
"description": "Short biography text"
},
"location": {
"type": "string",
"description": "Location string"
},
"avatar_url": {
"type": "string",
"format": "uri",
"description": "URL to the person's avatar image"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the person's account was created"
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the person's profile was last updated"
},
"admin": {
"type": "boolean",
"description": "Whether the person is an account administrator"
},
"owner": {
"type": "boolean",
"description": "Whether the person is the account owner"
},
"client": {
"type": "boolean",
"description": "Whether the person is a client user"
},
"employee": {
"type": "boolean",
"description": "Whether the person is an internal employee"
},
"time_zone": {
"type": "string",
"description": "IANA time zone name for the person's local time zone"
}
}
},
"Bucket": {
"type": "object",
"description": "Reference to the Basecamp project containing the recording",
"required": ["id", "name", "type"],
"properties": {
"id": {
"type": "integer",
"description": "Project ID"
},
"name": {
"type": "string",
"description": "Project name"
},
"type": {
"type": "string",
"description": "Always 'Project' for project buckets",
"const": "Project"
}
}
},
"Recording": {
"type": "object",
"description": "A Basecamp content resource such as a message, to-do, document, comment, or card. The exact fields present depend on the resource type indicated by the type field.",
"required": ["id", "type"],
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier for this recording"
},
"status": {
"type": "string",
"description": "Lifecycle status of the recording",
"enum": ["active", "archived", "trashed"]
},
"visible_to_clients": {
"type": "boolean",
"description": "Whether the recording is visible to client users"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the recording was created"
},
"updated_at": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the recording was last updated"
},
"title": {
"type": "string",
"description": "Title or summary of the recording"
},
"inherits_status": {
"type": "boolean",
"description": "Whether this recording inherits its status from a parent recording"
},
"type": {
"type": "string",
"description": "Recording type identifying the kind of Basecamp content",
"enum": [
"Message",
"Todo",
"Todolist",
"Document",
"Comment",
"Kanban::Card",
"Schedule::Entry",
"Upload",
"Vault",
"Question::Answer",
"Client::Forward",
"Client::Correspondence",
"Inbox::Forward"
]
},
"url": {
"type": "string",
"format": "uri",
"description": "API URL to retrieve this recording"
},
"app_url": {
"type": "string",
"format": "uri",
"description": "Web URL to open this recording in the Basecamp application"
},
"bookmark_url": {
"type": "string",
"format": "uri",
"description": "API URL to bookmark this recording"
},
"bucket": {
"$ref": "#/$defs/Bucket"
},
"creator": {
"$ref": "#/$defs/Person"
},
"content": {
"type": "string",
"description": "HTML-formatted body content for messages, documents, and comments"
},
"subject": {
"type": "string",
"description": "Subject line for message recordings"
},
"completed": {
"type": "boolean",
"description": "Whether the to-do has been completed (Todo type only)"
},
"due_on": {
"type": ["string", "null"],
"format": "date",
"description": "Due date in ISO 8601 date format (Todo type only)"
},
"starts_on": {
"type": ["string", "null"],
"format": "date",
"description": "Start date in ISO 8601 date format (Todo type only)"
},
"assignees": {
"type": "array",
"description": "People assigned to this to-do (Todo type only)",
"items": {
"$ref": "#/$defs/Person"
}
},
"starts_at": {
"type": "string",
"format": "date-time",
"description": "Start time for schedule entries (Schedule::Entry type only)"
},
"ends_at": {
"type": "string",
"format": "date-time",
"description": "End time for schedule entries (Schedule::Entry type only)"
},
"all_day": {
"type": "boolean",
"description": "Whether the schedule entry spans the entire day (Schedule::Entry type only)"
},
"filename": {
"type": "string",
"description": "Original filename of the uploaded file (Upload type only)"
},
"content_type": {
"type": "string",
"description": "MIME type of the uploaded file (Upload type only)"
},
"byte_size": {
"type": "integer",
"description": "File size in bytes (Upload type only)"
},
"download_url": {
"type": "string",
"format": "uri",
"description": "Direct download URL for the uploaded file (Upload type only)"
},
"comments_count": {
"type": "integer",
"description": "Number of comments on this recording"
},
"boosts_count": {
"type": "integer",
"description": "Number of boosts (reactions) on this recording"
},
"position": {
"type": "integer",
"description": "Display order position within the parent container"
},
"parent": {
"$ref": "#/$defs/Recording",
"description": "Reference to the parent recording (e.g., the message board containing a message, or the to-do list containing a to-do)"
}
}
}
}
}