Skip to main content
POST
/
track
/
sale
Python
from dub import Dub


with Dub(
    token="DUB_API_KEY",
) as d_client:

    res = d_client.track.sale(request={
        "customer_external_id": "<id>",
        "amount": 594903,
        "event_name": "Invoice paid",
        "lead_event_name": "Cloned template 1481267",
    })

    # Handle response
    print(res)
declare(strict_types=1);

require 'vendor/autoload.php';

use Dub;
use Dub\Models\Operations;

$sdk = Dub\Dub::builder()
->setSecurity(
'DUB_API_KEY'
)
->build();

$request = new Operations\TrackSaleRequestBody(
customerExternalId: '<id>',
amount: 594903,
eventName: 'Invoice paid',
leadEventName: 'Cloned template 1481267',
);

$response = $sdk->track->sale(
request: $request
);

if ($response->object !== null) {
// handle response
}
package main

import(
"context"
dubgo "github.com/dubinc/dub-go"
"github.com/dubinc/dub-go/models/operations"
"log"
)

func main() {
ctx := context.Background()

s := dubgo.New(
dubgo.WithSecurity("DUB_API_KEY"),
)

res, err := s.Track.Sale(ctx, &operations.TrackSaleRequestBody{
CustomerExternalID: "<id>",
Amount: 594903,
EventName: dubgo.Pointer("Invoice paid"),
LeadEventName: dubgo.Pointer("Cloned template 1481267"),
})
if err != nil {
log.Fatal(err)
}
if res != nil {
// handle response
}
}
require 'dub'

Models = ::OpenApiSDK::Models
s = ::OpenApiSDK::Dub.new(
security: Models::Shared::Security.new(
token: 'DUB_API_KEY',
),
)

req = Models::Operations::TrackSaleRequestBody.new(
customer_external_id: '<id>',
amount: 594_903,
event_name: 'Invoice paid',
lead_event_name: 'Cloned template 1481267',
)

res = s.track.sale(request: req)

unless res.nil?
# handle response
end
import { Dub } from "dub";

const dub = new Dub({
token: "DUB_API_KEY",
});

async function run() {
const result = await dub.track.sale();

console.log(result);
}

run();
curl --request POST \
--url https://api.dub.co/track/sale \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"customerExternalId": "<string>",
"amount": 1,
"currency": "usd",
"eventName": "Invoice paid",
"paymentProcessor": "custom",
"invoiceId": null,
"metadata": null,
"leadEventName": "Cloned template 1481267",
"clickId": "<string>",
"customerName": null,
"customerEmail": null,
"customerAvatar": null
}
'
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
customerExternalId: '<string>',
amount: 1,
currency: 'usd',
eventName: 'Invoice paid',
paymentProcessor: 'custom',
invoiceId: null,
metadata: null,
leadEventName: 'Cloned template 1481267',
clickId: '<string>',
customerName: null,
customerEmail: null,
customerAvatar: null
})
};

fetch('https://api.dub.co/track/sale', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
HttpResponse<String> response = Unirest.post("https://api.dub.co/track/sale")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"customerExternalId\": \"<string>\",\n \"amount\": 1,\n \"currency\": \"usd\",\n \"eventName\": \"Invoice paid\",\n \"paymentProcessor\": \"custom\",\n \"invoiceId\": null,\n \"metadata\": null,\n \"leadEventName\": \"Cloned template 1481267\",\n \"clickId\": \"<string>\",\n \"customerName\": null,\n \"customerEmail\": null,\n \"customerAvatar\": null\n}")
.asString();
{
  "eventName": "<string>",
  "customer": {
    "id": "<string>",
    "name": "<string>",
    "email": "<string>",
    "avatar": "<string>",
    "externalId": "<string>"
  },
  "sale": {
    "amount": 123,
    "currency": "<string>",
    "paymentProcessor": "<string>",
    "invoiceId": "<string>",
    "metadata": {}
  }
}
{
"error": {
"code": "bad_request",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#bad-request"
}
}
{
"error": {
"code": "unauthorized",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#unauthorized"
}
}
{
"error": {
"code": "forbidden",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#forbidden"
}
}
{
"error": {
"code": "not_found",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#not-found"
}
}
{
"error": {
"code": "conflict",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#conflict"
}
}
{
"error": {
"code": "invite_expired",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#invite-expired"
}
}
{
"error": {
"code": "unprocessable_entity",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#unprocessable-entity"
}
}
{
"error": {
"code": "rate_limit_exceeded",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#rate-limit_exceeded"
}
}
{
"error": {
"code": "internal_server_error",
"message": "The requested resource was not found.",
"doc_url": "https://dub.co/docs/api-reference/errors#internal-server_error"
}
}

Authorizations

Authorization
string
header
required

Default authentication mechanism

Body

application/json
customerExternalId
string
required

The unique ID of the customer in your system. Will be used to identify and attribute all future events to this customer.

Required string length: 1 - 100
amount
integer
required

The amount of the sale in cents (for all two-decimal currencies). If the sale is in a zero-decimal currency, pass the full integer value (e.g. 1437 JPY). Learn more: https://d.to/currency

Required range: x >= 0
currency
string
default:usd

The currency of the sale. Accepts ISO 4217 currency codes. Sales will be automatically converted and stored as USD at the latest exchange rates. Learn more: https://d.to/currency

eventName
string
default:Purchase

The name of the sale event. Recommended format: Invoice paid or Subscription created.

Maximum string length: 255
Example:

"Invoice paid"

paymentProcessor
enum<string>
default:custom

The payment processor via which the sale was made.

Available options:
stripe,
shopify,
polar,
paddle,
revenuecat,
custom
invoiceId
string | null

The invoice ID of the sale. Can be used as a idempotency key – only one sale event can be recorded for a given invoice ID.

metadata
object | null

Additional metadata to be stored with the sale event. Max 10,000 characters when stringified.

leadEventName
string | null

The name of the lead event that occurred before the sale (case-sensitive). This is used to associate the sale event with a particular lead event (instead of the latest lead event for a link-customer combination, which is the default behavior). For direct sale tracking, this field can also be used to specify the lead event name.

Example:

"Cloned template 1481267"

clickId
string | null

[For direct sale tracking]: The unique ID of the click that the sale conversion event is attributed to. You can read this value from dub_id cookie.

customerName
string | null

[For direct sale tracking]: The name of the customer. If not passed, a random name will be generated (e.g. “Big Red Caribou”).

Maximum string length: 100
customerEmail
string<email> | null

[For direct sale tracking]: The email address of the customer.

Maximum string length: 100
customerAvatar
string | null

[For direct sale tracking]: The avatar URL of the customer.

Response

A sale was tracked.

eventName
string
required
customer
object | null
required
sale
object | null
required