Required scopes
The activity APIs use two scopes:activity_configurationfor reading and writing activities themselves and their attributes.activity_recordfor reading and writing activity records.
activity_configuration:read, object_configuration:read and record_permission:read. Creating referenced records as part of a write also needs record_permission:read-write.
Creating an activity
Create an activity withPOST /v2/activities. Besides a slug and its display names, you must pick the schema the activity extends: activities, interactions, calls or emails.
When creating custom activities, it’s good practice to prefix the slug with an app-specific prefix like {app_name}_site_visits to prevent conflicts.
PATCH /v2/activities/{activity} can update the slug and nouns, but rejects extends with a 400.
You can list all activities with GET /v2/activities and fetch a single one with GET /v2/activities/{activity}. Wherever {activity} appears in a path, you can pass either the activity’s UUID or its api_slug.
Deleting an activity
DELETE /v2/activities/{activity} deletes an activity and all of its records. It needs both activity_configuration:read-write and activity_record:read-write, and workspace members must be an admin. Archived activities can be deleted too.
Only custom activities can be changed. PATCH and DELETE on a system activity such as phone_calls fail with a 400.
Adding attributes
The attribute endpoints acceptactivities as a target, alongside objects and lists. For example, to add a “Location” attribute to the site visits activity:
timestamp or direction) are listed alongside your custom attributes and look identical in the API. However, they are managed by the schema: attempting to update them or to add select options to them fails with a 400 error explaining that the attribute is inherited.
Creating activity records
Log an event withPOST /v2/activities/{activity}/records. The body has the same shape as for object records: a values map keyed by attribute slug.
The example below logs an outbound renewal call on an activity extending the calls schema. It links the Acme company by domain and the participant by email address, without knowing any record IDs:
timestamp(when the event happened) is required on every activity record.created_atandcreated_byare set by the system and cannot be written.- The response contains the record’s composite ID (
workspace_id,activity_id,record_id), itscreated_atand all of itsvalues. Unlike object records, activity records have noweb_url.
Linking records by attribute value
Record reference values such aslinked_records and participants can be written in three formats, just like on object records:
- ID format:
{"target_object": "people", "target_record_id": "<uuid>"} - Matching format: identify the target record by one of its attribute values, e.g.
{"target_object": "people", "email_addresses": [{"email_address": "alice@acme.com"}]} - Target record reference format:
{"target_object": "people", "target_record_reference": {…}}, which also says what to do when nothing matches or several records match
- Exactly one record must match. If a matching value resolves to several records, e.g. a phone number shared by two people, the request fails with a
400instead of picking one arbitrarily. To link all of them, up to 50 records per value, use the target record reference format withif_multiple_matches: "match_all". - Duplicates are rejected. If the same record is referenced more than once in one attribute, for example by ID and by a matching value, the request fails with a
400. - Records are not created. If no record matches, the request fails with a
400naming the value that could not be found.
Querying activity records
Query records of an activity withPOST /v2/activities/{activity}/records/query. The body supports the same filter and sorts as object record queries, plus limit (default 500) and offset for pagination.
GET /v2/activities/{activity}/records/{record_id} (UUID only).
Activity records are also queryable with SQL: each activity is exposed as a table under the activities schema, named by its api_slug, e.g. activities.phone_calls. See Available data for the full picture of what’s queryable.
Updating activity records
Activity records support the same two update methods as object records:PUT /v2/activities/{activity}/records/{record_id}overwrites: for multiselect attributes, the values you supply replace the existing list of values.PATCH /v2/activities/{activity}/records/{record_id}appends: for multiselect attributes, the values you supply are added to the existing list of values.
values map, including all three record reference formats, as record creation.
Upserting activity records
PUT /v2/activities/{activity}/records?matching_attribute={attribute} creates an activity record, or updates the record that has the same value for the matching attribute. {attribute} is the slug or ID of an attribute on the activity, for example an ID from your own system. If more than one record matches the value, the request fails with a 400. It needs the same scopes as record creation.
Deleting activity records
DELETE /v2/activities/{activity}/records/{record_id} deletes a single activity record. It needs activity_record:read-write.
Webhooks
Activities emit seven webhook event types.
Every payload also carries an
actor. Note that the id of an activity event uses activity_id where an object event would use object_id.
Subscribing to one activity
A workspace can have many activities, andactivity-record.created fires for all of them. If you only care about one, use a filter on the subscription:
api_slug. The other fields you can filter on are id.workspace_id, id.record_id, id.attribute_id, actor.type and actor.id.
This is strongly recommended for activities: it keeps the deliveries you do not need from counting against your endpoint’s delivery rate limit.
Current limitations
- Activity records have no
web_url. - There is no
activity-record.updatedwebhook event. - Activities cannot be added to lists.
- The status endpoints do not accept
activitiesas a target. Use select attributes instead.
Activities concept guide
How activities, activity records and schemas fit into Attio’s data model.