---
title: "Update a customer"
description: "Opt a customer out of, or back into, the merchant's emails (marketing.unsubscribed), as the unsubscribe link in those emails does. :id is Filemonk's id or a Shopify Customer gid or id."
url: https://docs.filemonk.io/v2/api-reference/customers/update-a-customer/
api: "API v2 reference"
method: PATCH
path: "/customers/{id}"
---

# Update a customer

`PATCH https://app.filemonk.io/api/v2/external/customers/{id}`

Opt a customer out of, or back into, the merchant's emails (marketing.unsubscribed), as the unsubscribe link in those emails does. :id is Filemonk's id or a Shopify Customer gid or id.

**Note:** Delivery emails for new orders still go out; this covers the product-update emails. Like the unsubscribe link, it changes every customer of the shop with the same email address.

## Path parameters

- `id` (string, required)

## Request body

- `marketing` (object, required)
  - `unsubscribed` (boolean): e.g. `true`

## Returns

The [customer object](https://docs.filemonk.io/v2/api-reference/customers/).

Rate limit: this call costs 2 points ([rate limits](https://docs.filemonk.io/v2/errors-and-rate-limits/)).

## Example request

```sh
curl -X PATCH "https://app.filemonk.io/api/v2/external/customers/ca5b4abc-63b1-4e29-be0a-12acb35908c5" \
  -H "X-Auth-Token: $FILEMONK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "marketing": {
      "unsubscribed": true
    }
  }'
```

## 200

Success: the write completed; the body is the updated resource.

```json
{
  "id": "ca5b4abc-63b1-4e29-be0a-12acb35908c5",
  "shopify_customer_id": "gid://shopify/Customer/10296813191463",
  "email": null,
  "phone": null,
  "first_name": "Jane",
  "last_name": "Doe",
  "orders_count": 1,
  "marketing": {
    "unsubscribed": true,
    "unsubscribed_at": "2026-10-30T23:10:00Z"
  },
  "created_at": "2026-10-26T14:19:29Z",
  "updated_at": "2026-10-26T14:19:29Z"
}
```

## 401

Missing or invalid API key.

```json
{
  "errors": [
    "Invalid API key"
  ]
}
```

## 404

The resource does not exist for this shop, or the action path is not registered.

```json
{
  "errors": [
    "Order not found: c3d4e5f6-7a8b-4c9d-8e0f-1a2b3c4d5e6f"
  ]
}
```

## 422

The request failed validation, or sent a key the action does not take (`code: &quot;unknown_parameters&quot;` with `unknown` and `accepted`). Nothing was saved.

```json
{
  "errors": [
    "access.download_limit_count must be an integer of at least 0"
  ],
  "field_errors": {
    "access.download_limit_count": [
      "must be an integer of at least 0"
    ]
  }
}
```

## 429

Rate limited. Cost-weighted per API key, shared with API v1: a read costs 1 point, a write 2, 40 points per fixed 60-second window. Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (Unix time the window ends); a 429 adds `Retry-After` (seconds), `retry_after`, `retryable: true` and a `next_step` in the body. A 429 did nothing: wait `retry_after` seconds, then send the same request again. The budget is per key, so every tool or script using the key shares it; prefer one list call with `per_page` over many single reads.

```json
{
  "errors": [
    "You have exceeded the rate limit of 40 points per 60 seconds. Read requests cost 1 point(s) and write requests cost 2 point(s). Please retry after 12 second(s)."
  ],
  "code": "rate_limited",
  "retry_after": 12,
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit of 40 points per 60 seconds. Read requests cost 1 point(s) and write requests cost 2 point(s). Please retry after 12 second(s)."
}
```

