> ## 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.

# Record Revenue

> Record revenue attribution for a sent message.

Record a single revenue event against a previously sent message. The message is looked up by its opaque, variable-length message identifier. If an offer is not explicitly provided, the system will attempt to resolve it from the message's short link.

## Authentication

<ParamField header="X-Api-Key" type="string" required>
  Your Trackly SMS API key. Format: `trk_[32-char-hex]`.
</ParamField>

## Body Parameters

<ParamField body="message_id" type="string" required>
  The opaque, variable-length message identifier returned when the message was sent. This is the same value passed via the `{{sendId}}` macro.
</ParamField>

<ParamField body="revenue" type="float" required>
  Revenue amount to attribute. Must be greater than or equal to `0`.
</ParamField>

<ParamField body="attribution_type" type="string" required>
  How the revenue was attributed. One of: `sale`, `click`, or `send`.
</ParamField>

<ParamField body="offer_id" type="string">
  The offer ID this revenue is associated with. Can be either the `externalId` or the offer ID generated by TracklySMS. If omitted, the system will attempt to resolve the offer from the message's short link.
</ParamField>

<ParamField body="timestamp" type="datetime">
  ISO 8601 timestamp for the revenue event. Assumed to be UTC if no timezone is provided. Defaults to the current time if omitted.
</ParamField>

## Response Fields

<ResponseField name="success" type="boolean">
  Whether the revenue was recorded successfully.
</ResponseField>

<ResponseField name="revenue_id" type="string">
  The unique ID of the created revenue record.
</ResponseField>

<ResponseField name="message_id" type="string">
  The message ID the revenue was attributed to.
</ResponseField>

<ResponseField name="revenue" type="float">
  The revenue amount that was recorded.
</ResponseField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST https://api.tracklysms.com/api/v2/revenue \
      -H "X-Api-Key: trk_your_api_key_here" \
      -H "Content-Type: application/json" \
      -d '{
        "message_id": "a1b2c3d4",
        "revenue": 24.99,
        "offer_id": "offer_123",
        "attribution_type": "sale",
        "timestamp": "2026-02-08T12:00:00Z"
      }'
    ```

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

    response = requests.post(
        "https://api.tracklysms.com/api/v2/revenue",
        headers={
            "X-Api-Key": "trk_your_api_key_here",
            "Content-Type": "application/json",
        },
        json={
            "message_id": "a1b2c3d4",
            "revenue": 24.99,
            "offer_id": "offer_123",
            "attribution_type": "sale",
            "timestamp": "2026-02-08T12:00:00Z",
        },
    )

    print(response.json())
    ```

    ```javascript Node.js theme={null}
    const response = await fetch("https://api.tracklysms.com/api/v2/revenue", {
      method: "POST",
      headers: {
        "X-Api-Key": "trk_your_api_key_here",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        message_id: "a1b2c3d4",
        revenue: 24.99,
        offer_id: "offer_123",
        attribution_type: "sale",
        timestamp: "2026-02-08T12:00:00Z",
      }),
    });

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

<ResponseExample>
  ```json 201 - Success theme={null}
  {
    "success": true,
    "revenue_id": "67a1b2c3d4e5f6a7b8c9d0e1",
    "message_id": "a1b2c3d4",
    "revenue": 24.99
  }
  ```

  ```json 400 - Validation Error theme={null}
  {
    "code": "invalid_attribution_type",
    "error": "attribution_type must be one of: click, sale, send"
  }
  ```

  ```json 400 - Not Found theme={null}
  {
    "code": "message_not_found",
    "error": "Message ID not found"
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code                 | Description                                          |
| ----------- | -------------------------- | ---------------------------------------------------- |
| 400         | `missing_message_id`       | The `message_id` field is required.                  |
| 400         | `missing_revenue`          | The `revenue` field is required.                     |
| 400         | `missing_attribution_type` | The `attribution_type` field is required.            |
| 400         | `invalid_message_id`       | The `message_id` field must be a string.             |
| 400         | `invalid_body`             | The request body must be a JSON object.              |
| 400         | `invalid_revenue`          | Revenue must be a number greater than or equal to 0. |
| 400         | `invalid_attribution_type` | Must be one of: `sale`, `click`, or `send`.          |
| 400         | `message_not_found`        | No message exists with the given ID.                 |

## Next Steps

<CardGroup cols={2}>
  <Card title="Revenue Tracking" icon="chart-line" href="/guides/offers/revenue-tracking">
    Track and attribute revenue
  </Card>

  <Card title="Send Message" icon="paper-plane" href="/api-reference/v2/messages/send-single">
    Send messages to drive revenue
  </Card>
</CardGroup>
