> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Offer

> Update an existing offer. Only provided fields are modified.

Updates an existing offer on your account. Only the fields included in the request body are modified -- omitted fields remain unchanged. The `metadata` field is merged with existing metadata rather than replaced, allowing you to add or update individual keys without losing others.

## Path Parameters

<ParamField path="id" type="string" required>
  The unique identifier of the offer to update.
</ParamField>

## Body Parameters

<ParamField body="name" type="string" optional>
  Display name for the offer. Maximum 255 characters.
</ParamField>

<ParamField body="tracking_url" type="string" optional>
  The tracking/click URL for this offer. Must be a valid URL.
</ParamField>

<ParamField body="external_platform" type="string" optional>
  External affiliate platform integration. Accepted values: `tune`, `everflow`, or `null`.
</ParamField>

<ParamField body="external_id" type="string" optional>
  The offer ID on the external platform.
</ParamField>

<ParamField body="advertiser_id" type="string" optional>
  Advertiser ID associated with the offer.
</ParamField>

<ParamField body="payout" type="float" optional>
  Payout amount for the offer.
</ParamField>

<ParamField body="payout_type" type="string" optional>
  Payout model. Accepted values: `cpa` (cost per action) or `cpc` (cost per click).
</ParamField>

<ParamField body="filter_bots" type="boolean" optional>
  Whether to enable bot click filtering for this offer.
</ParamField>

<ParamField body="status" type="string" optional>
  Status of the offer. Accepted values: `active`, `paused`, or `archived`. Setting status to `archived` is equivalent to a soft delete.
</ParamField>

<ParamField body="metadata" type="object" optional>
  Custom key-value pairs. Merged with existing metadata -- new keys are added, existing keys are overwritten, and keys not included in the request are preserved. Stored as-is; no type validation is enforced on keys or values.
</ParamField>

<ParamField body="excluded_days_of_week" type="array" optional>
  Weekday names (lowercase `monday` through `sunday`) on which the SMS ad server will not send this offer, evaluated in the contact's local time. Replaces the existing list; duplicates are removed and the list is normalized to weekday order.
</ParamField>

<ParamField body="day_parting_enabled" type="boolean" optional>
  Whether intra-day send-window restrictions apply. When the resulting `day_parting_enabled` is `true`, the resulting `day_parting` must be non-empty or the request is rejected with `invalid_day_parting`.
</ParamField>

<ParamField body="day_parting" type="object" optional>
  Allow-list of send windows keyed by lowercase weekday, evaluated in Eastern Time. Shape: `{"monday": [{"start": "HH:MM", "end": "HH:MM"}]}`. Times are 24-hour zero-padded; `start` must be before `end` (no overnight crossing); maximum 6 ranges per day. Omit a weekday to block sending on that day. Replaces the existing value.
</ParamField>

## Response Fields

The response is the full updated offer object (flat, not wrapped). See [List Offers](/api-reference/v2/offers/list-offers) for the complete field reference.

## Examples

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X PUT "https://api.tracklysms.com/api/v2/offers/664f1a2b3c4d5e6f7a8b9c0d" \
      -H "X-Api-Key: trk_your_api_key_here" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Summer Promo v2",
        "payout": 3.00,
        "metadata": {
          "geo": "US,CA",
          "notes": "Updated payout for Q1"
        }
      }'
    ```

    ```python Python theme={null}
    import requests

    offer_id = "664f1a2b3c4d5e6f7a8b9c0d"

    response = requests.put(
        f"https://api.tracklysms.com/api/v2/offers/{offer_id}",
        headers={
            "X-Api-Key": "trk_your_api_key_here",
            "Content-Type": "application/json"
        },
        json={
            "name": "Summer Promo v2",
            "payout": 3.00,
            "metadata": {
                "geo": "US,CA",
                "notes": "Updated payout for Q1"
            }
        }
    )

    data = response.json()
    print(data["name"], data["payout"])
    ```

    ```javascript Node.js theme={null}
    const offerId = "664f1a2b3c4d5e6f7a8b9c0d";

    const response = await fetch(
      `https://api.tracklysms.com/api/v2/offers/${offerId}`,
      {
        method: "PUT",
        headers: {
          "X-Api-Key": "trk_your_api_key_here",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          name: "Summer Promo v2",
          payout: 3.00,
          metadata: {
            geo: "US,CA",
            notes: "Updated payout for Q1"
          }
        })
      }
    );

    const data = await response.json();
    console.log(data.name, data.payout);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "id": "664f1a2b3c4d5e6f7a8b9c0d",
    "slug": "ofr_summer-promo-v2_a1b2c3",
    "name": "Summer Promo v2",
      "tracking_url": "https://track.example.com/click?offer_id=123",
      "external_platform": "tune",
      "external_id": "4521",
      "advertiser_id": "adv_882",
      "advertiser_name": null,
      "payout": 3.00,
      "payout_type": "cpa",
      "filter_bots": true,
      "status": "active",
      "metadata": {
        "vertical": "health",
        "geo": "US,CA",
        "notes": "Updated payout for Q1"
      },
      "excluded_days_of_week": [],
      "day_parting_enabled": false,
      "day_parting": {},
      "created_at": "2025-11-01T14:30:00",
      "updated_at": "2026-01-10T16:45:00"
  }
  ```

  ```json 400 - Validation Error theme={null}
  {
    "error": "name must be 255 characters or less",
    "code": "name_too_long"
  }
  ```

  ```json 404 - Not Found theme={null}
  {
    "error": "Offer not found",
    "code": "not_found"
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "error": "Invalid credentials",
    "code": "invalid_credentials"
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code                  | Description                                                                                               |
| ----------- | --------------------------- | --------------------------------------------------------------------------------------------------------- |
| 400         | `name_too_long`             | The `name` exceeds 255 characters.                                                                        |
| 400         | `invalid_external_platform` | The `external_platform` value is not `tune`, `everflow`, or `null`.                                       |
| 400         | `invalid_payout_type`       | The `payout_type` value is not `cpa` or `cpc`.                                                            |
| 400         | `invalid_status`            | The `status` value is not `active`, `paused`, or `archived`.                                              |
| 400         | `invalid_excluded_days`     | `excluded_days_of_week` is not a list or contains a non-weekday value.                                    |
| 400         | `invalid_day_parting`       | `day_parting` is malformed, or the resulting `day_parting_enabled` is `true` with an empty `day_parting`. |
| 401         | `invalid_credentials`       | API key is missing or invalid.                                                                            |
| 403         | `account_suspended`         | Your account is suspended. Resolve outstanding billing or contact support.                                |
| 429         | `rate_limited`              | Request throttled; retry with exponential backoff after the window resets.                                |
| 404         | `not_found`                 | No offer exists with the specified ID.                                                                    |
| 500         | `server_error`              | An unexpected error occurred on the server.                                                               |

## Next Steps

<CardGroup cols={2}>
  <Card title="Offers Overview" icon="tag" href="/guides/offers/overview">
    Manage offers and payouts
  </Card>

  <Card title="Record Revenue" icon="dollar-sign" href="/api-reference/v2/revenue/record-revenue">
    Track revenue for this offer
  </Card>
</CardGroup>
