# Change a message participant

```http
PUT https://secure.yoprint.com/v1/api/store/{team_slug}/participant/{id}
```

- API version: v1
- Operation ID: `v1_public_participant_update_put`
- Section: Messages and activity › [Message participants](https://developer.yoprint.com/reference/message-participants.md)
- Web page: https://developer.yoprint.com/reference/message-participants/v1-participant-update-put/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Changes what a participant receives on an order's or purchase order's message thread. It can't change where their messages go: a participant's email address and contact are fixed once added. To reach another address or contact, add it as a new participant with the order's participant operations, and remove this one if you like.

**Always send `status`.** If you leave it out, it is reset to `all`.

- To change what they receive, send `status` and, if you like, `can_receive_mail` and `can_receive_sms`.
- To turn a guest into a contact, send `type: "contact"` with `contact_id`. The contact must belong to the order's customer (or the purchase order's vendor) and have the guest's email address.
- A guest's `name` can change. For a contact or team member, name, email and phone come from their own record; change them there.

## Permission

Any member of the team, for any participant on the team.

## Business rules

- `status` is `message`, `notification`, `all` or `disabled`; left out, it becomes `all`.
- A participant's email address can't change. Without `type`, sending an `email` other than the address stored on the participant (compared ignoring case and surrounding spaces) is refused: 422 `participant_email_immutable`, "A recipient's email address can't be changed. Add the new address as a new recipient." For a contact or team member, the `email` you read comes from their own record, not from the participant, so sending it back can be refused: leave `email` out.
- Sending `type` (whatever its value) needs `contact_id`, a contact of your team (otherwise 404). `type: "guest"` can't be used here.
- The participant's contact can't be switched. `contact_id` may be the current contact (nothing changes) or, only for a guest, a contact of the order's customer (or the purchase order's vendor) whose email is the guest's address: the guest then becomes that contact. Anything else, including a team member, is refused: 422 `participant_destination_immutable`, "A recipient can't be switched to another contact. Add the contact as a new recipient."
- A refused change saves nothing, not even `status`.

## Side effects

- Changes what the participant receives from the order's future customer emails and texts. Past messages are unchanged.
- People with the order open see the change live.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `id` (string, required): The participant's `id`, from the order's participant list. A hash id; unique keys and document numbers are refused with 404. Example `vKNPqQz8fsYDuT`.

## Request body

Content type `application/json`, optional.

Fields:

- `type` (string, optional): Send `contact` together with `contact_id` to turn a guest into that contact. Sending `type` always requires `contact_id`. Always `"contact"`.
- `can_receive_mail` (boolean, optional): Unchanged when left out.
- `can_receive_sms` (boolean, optional): Unchanged when left out.
- `contact_id` (string, optional): A contact of your team. Used only with `type`. It must be the participant's current contact or, for a guest, a contact of the order's customer (or the purchase order's vendor) with the guest's email address.
- `email` (string (email), optional): Can't be changed: leave it out. Without `type`, an address other than the one stored on the participant is refused with 422 `participant_email_immutable`; the same address (ignoring case and surrounding spaces) changes nothing. Ignored with `type`.
- `name` (string, optional): A guest's name. It is saved for contacts and team members too, but their name always comes from their own record.
- `status` (string, optional): What they receive. The emails and texts YoPrint sends on the order by itself go only to `all` and `message`. Becomes `all` when left out. One of: `"message"`, `"notification"`, `"all"`, `"disabled"`.

### Example request

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/participant/vKNPqQz8fsYDuT' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "contact_id": "QKyWRMoL0kTU05",
    "status": "all",
    "type": "contact"
  }'
```

Another example: Keep emails, stop texts:

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/participant/vKNPqQz8fsYDuT' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "can_receive_mail": true,
    "can_receive_sms": false,
    "status": "all"
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (object, required)
  - `can_receive_mail` (boolean, optional)
  - `can_receive_sms` (boolean, optional)
  - `contact` (object | null, optional): The contact's own record (`id`, `first_name`, `last_name`, `email`, `phone`, `phone_country`, `customer_id` or `vendor_id`, and more). Null when the participant has no contact.
  - `contact_id` (string | null, optional)
  - `delivery_channel` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_created_at` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_destination` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_destination_name` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_id` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_latest_error_reason` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_message_id` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_participant_id` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_state` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_status` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `delivery_updated_at` (string | null, optional): Always null here. Set only when the participant is read as one of a message's recipients.
  - `email` (string | null, optional)
  - `id` (string, optional)
  - `name` (string | null, optional)
  - `order_id` (string | null, optional)
  - `phone` (string | null, optional): A contact's phone. Null for team members and guests.
  - `purchase_order_id` (string | null, optional)
  - `status` (string, optional): What they get. The emails and texts YoPrint sends on the order by itself (approval requests, order details, reminders) go only to `all` and `message`; `notification` and `disabled` get none of them. One of: `"message"`, `"notification"`, `"all"`, `"disabled"`.
  - `trashed` (boolean, optional): Always false here: a removed participant answers 404.
  - `type` (string, optional): `user`: a team member. `contact`: one of the customer's or vendor's contacts (name, email and phone come from the contact). `guest`: just a name and email. One of: `"user"`, `"contact"`, `"guest"`.
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "can_receive_mail": true,
    "can_receive_sms": false,
    "contact": {
      "created_at": "2026-11-01T09:00:00+00:00",
      "customer_id": "63KcENAAsKuipY",
      "default_receive_sms": false,
      "email": "jordan@example.com",
      "external_type": null,
      "fax": null,
      "fax_country": null,
      "first_name": "Jordan",
      "id": "uTCR3hxPDePBUK",
      "is_external": false,
      "is_primary": true,
      "last_name": "Lee",
      "phone": "+1 201 555 0123",
      "phone_country": "US",
      "send_invoice": true,
      "trashed": false,
      "updated_at": "2026-11-01T09:00:00+00:00"
    },
    "contact_id": "uTCR3hxPDePBUK",
    "delivery_channel": null,
    "delivery_created_at": null,
    "delivery_destination": null,
    "delivery_destination_name": null,
    "delivery_id": null,
    "delivery_latest_error_reason": null,
    "delivery_message_id": null,
    "delivery_participant_id": null,
    "delivery_state": null,
    "delivery_status": null,
    "delivery_updated_at": null,
    "email": "jordan@example.com",
    "id": "vKNPqQz8fsYDuT",
    "name": "Jordan Lee",
    "order_id": "V4keXwwxMQyXw7",
    "phone": "+1 201 555 0123",
    "purchase_order_id": null,
    "status": "all",
    "trashed": false,
    "type": "contact"
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: The participant does not exist, or `type` was sent without a valid `contact_id`. Fix: Use ids from the API, and send `contact_id` whenever you send `type`.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: A value is not allowed, for example `status` or `email` (`PUT`) (`validation_failed`; `error.fields` names the field). Fix: Send values from the lists here.
  - When: `email` differs from the participant's stored address (`participant_email_immutable`). Fix: Leave `email` out. To reach another address, add it as a new participant.
  - When: `contact_id` would switch the participant to another contact (`participant_destination_immutable`). Only a guest can become a contact, of the order's customer (or the purchase order's vendor), with the same address. Fix: Add the contact as a new participant instead.

## Related

- [Get a message participant](https://developer.yoprint.com/reference/message-participants/v1-participant-show.md): `GET /v1/api/store/{team_slug}/participant/{id}`
- [Add a participant to an order](https://developer.yoprint.com/reference/sales-order-messages/v1-sales-order-participant-store.md): `POST /v1/api/store/{team_slug}/sales_order/{hash_id}/participant`
