---
title: "Update a participant"
method: PATCH
path: "/v1/participants/{participant_id}"
tags: ["Participants"]
---

# Update a participant

`PATCH /v1/participants/{participant_id}`

## Request

- Base URL: `https://api.scrip.dev`
- URL: `https://api.scrip.dev/v1/participants/{participant_id}`
- Auth: HTTP bearer

Change a participant's status, contact details, tags, attributes and counters in one request. Scrip applies every change together or none of them, and returns the participant with its updated state.

## Path parameters

- `participant_id` string, required

## Headers

- `Idempotency-Key` string

## Request body

- UpdateParticipantRequest: Changes a participant's profile, status, tags, attributes or counters. Send only the fields to change.
  - `attributes` object: Attributes to change, as a merge patch. Keys you send are set, keys you leave out keep their value, and a key sent as null is removed. Removing a key that does not exist succeeds and changes nothing, so retries are safe. Rules read each key as `participant.attribute.<key>` or with `get(participant.attributes, "key", "")`.
  - `counters` object: Counters to change. Each key maps to `{"increment": n}` to add to the counter, `{"set": n}` to replace its value, `{"reset_after": "720h"}` to change only the reset window and keep the value, or null to remove it. Removing a counter that does not exist succeeds and changes nothing, so retries are safe. Scrip applies every change in the request together or none of them. Counters need an ACTIVE participant.
  - `display_name` string: Display name. Empty string clears the value
  - `email` string: Contact email. Empty string clears the value
  - `first_name` string: First name. Empty string clears the value
  - `force` boolean: When true, suspending or closing the sole active ADMIN of a group proceeds and ends that participant's ADMIN membership in each such group; otherwise the request returns 409 `last_admin_status_change_forbidden`.
  - `last_name` string: Last name. Empty string clears the value
  - `phone` string: Contact phone. Empty string clears the value
  - `status` 'ACTIVE' | 'SUSPENDED' | 'CLOSED': Lifecycle state
  - `tags` string[]: The participant's full tag set. Sending tags replaces every existing tag, and an empty list removes them all. Leave the field out to keep the tags. null is not allowed.

## Response `200`

Participant updated

- ParticipantDetailResponse: A participant with their attributes, counters, tags, program memberships, tiers and balances.
  - `attributes` object: Key-value metadata. Rules read each key as `participant.attribute.<key>`, which is null if unset, or with `get(participant.attributes, "key", "")`. An empty object when the participant has none.
  - `balances` Balance[]: Current balances per asset, split by bucket
    - `asset_id` string, uuid: Asset the balance is in.
    - `available` string: Amount in the available bucket. For a `LOT` asset, it can include value past its `expires_at` for a few minutes, until Scrip records the expiration.
    - `deferred` string: Amount that becomes available when its `matures_at` time passes.
    - `held` string: Amount set aside by a hold or waiting as pending rewards; it cannot be spent until it is released or settled.
  - `counter_settings` object: Auto-reset settings for the counters that have one, keyed by counter key. An empty object when no counter resets. Set them with `reset_after` on a counter in PATCH.
  - `counters` object: Numeric accumulators, returned as strings for precision. An empty object when the participant has none.
  - `created_at` string, date-time: When the participant was created
  - `display_name` string: The name to show for the participant.
  - `email` string: Contact email
  - `external_id` string: Your application's identifier for this participant
  - `first_name` string: The participant's first name.
  - `id` string, uuid: The id of the participant. Use it in `participant_id` fields and paths.
  - `last_name` string: The participant's last name.
  - `phone` string: Contact phone
  - `program_ids` string[]: Programs this participant is enrolled in
  - `status` 'ACTIVE' | 'SUSPENDED' | 'CLOSED': The participant's lifecycle state.
  - `tags` string[]: Labels for segmentation. Rules read a tag as `participant.tag.<name>` (true or false) or `'name' in participant.tags`. An empty list when the participant has none.
  - `tiers` object: Current tier level per tier type
  - `updated_at` string, date-time: When the participant was last modified

## Other responses

- `400`: Validation failed (code: validation_error | invalid_json)
- `401`: The API key is missing or not valid. See [Authentication](https://docs.scrip.dev/authentication).
- `403`: The caller is not allowed to do this.
- `404`: Participant not found (code: participant_not_found)
- `409`: A status change would leave a group with no active ADMIN (retry with force), counters were sent for a participant that is not ACTIVE, or the Idempotency-Key conflicts with another request (code: last_admin_status_change_forbidden | participant_inactive | idempotency_conflict | idempotency_in_flight)
- `429`: Too many requests. Wait the number of seconds in the `Retry-After` header, then retry. See [Limits and durations](https://docs.scrip.dev/limits#rate-limits).
- `500`: Something failed on Scrip's side. Retry the request, and quote `request_id` if it keeps failing. [Errors](https://docs.scrip.dev/errors) lists every code, and the [API introduction](https://docs.scrip.dev/api-reference/introduction) describes the error format.

---

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