---
title: "Upsert an activity record"
method: PUT
path: "/v2/activities/{activity}/records"
tags: ["Activity records"]
---

# Upsert an activity record

`PUT /v2/activities/{activity}/records`

## Request

- Base URL: `https://api.attio.com`
- URL: `https://api.attio.com/v2/activities/{activity}/records`
- Auth: OAuth 2
  - Authorization code: `https://app.attio.com/authorize`
  - Token URL: `https://app.attio.com/oauth/token` scopes: `activity_record:read-write`, `activity_configuration:read`, `object_configuration:read`, `record_permission:read`

Use this endpoint to create or update an activity record. A matching attribute is used to search for existing activity records. If a record is found with the same value for the matching attribute, that record will be updated. If no record with the same value for the matching attribute is found, a new record will be created instead. If you would like to avoid matching, please use the [Create activity record endpoint](/rest-api/endpoint-reference/activity-records/create-an-activity-record).

If the matching attribute is a multiselect attribute, new values will be added and existing values will not be deleted. For any other multiselect attribute, all values will be either created or deleted as necessary to match the list of supplied values.

This endpoint is in beta. We will aim to avoid breaking changes, but small updates may be made as we roll out to more users.

Required scopes: `activity_record:read-write`, `activity_configuration:read`, `object_configuration:read`, `record_permission:read`.

Supported token levels: `workspace`, `user`.

## Path parameters

- `activity` string, required: A UUID or slug to identify the activity.

## Query parameters

- `matching_attribute` string, required: The ID or slug of the attribute to use to check if an activity record already exists. The attribute does not have to be unique, but a value that matches more than one record is rejected. We recommend a unique attribute, such as a domain, an email address or an ID from your own system.

## Request body

- object
  - `data` object, required
    - `values` object, required: An object with an attribute `api_slug` or `attribute_id` as the key, and a single value (for single-select attributes), or an array of values (for single or multi-select attributes) as the values. For complete documentation on values for all attribute types, please see our [attribute type docs](/docs/attribute-types).

## Response `200`

Success

- object: Success
  - `data` object, required
    - `id` object, required
      - `workspace_id` string, uuid, required: A UUID identifying the workspace this activity record belongs to.
      - `activity_id` string, uuid, required: A UUID identifying the activity this record belongs to.
      - `record_id` string, uuid, required: A UUID identifying this activity record.
    - `created_at` string, required: When this activity record was created.
    - `values` object, required: A record type with an attribute `api_slug` as the key, and an array of value objects as the values.

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict

## Changes

- **2026-10-15** `81e667ad2d75`: 1 breaking, 3 info
  - the `code` response's property type changed from `string` to no type for status `409`
  - added `subschema #1, subschema #2, subschema #3` to the `code` response property `anyOf` list for the response status `409`
  - added `subschema #5, subschema #6, subschema #7` to the `code` response property `anyOf` list for the response status `400`
  - removed the `concurrent_write_conflict` enum value from the `code` response property for the response status `409`
- **2026-09-25** `cd264259a8e8`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/attio/apis/attio-api/changes/v2/activities/:activity/records/put.md)

---

[API](https://skmtc.dev/attio/apis/attio-api.md) - [All operations](https://skmtc.dev/attio/apis/attio-api/llms.txt) - [OpenAPI document](https://skmtc.dev/attio/apis/attio-api/revisions/7d2c7472b378?raw)
