Yep Platform logo
REST API · Yep Platform Technical documentation for certified integrations

Sell by Link

Contract for external integrations to create personalized sales and obtain the order checkout link. In a single operation, the endpoint creates the sale, its items and the checkout link — the total is calculated by the server. You can then look up the sale and the custom options accepted by each product.

REST JSON Bearer Token New in 2026

Overview

Sell by Link exposes a POST contract to create the sale and the link, plus two auxiliary GET contracts — one to look up the sale state and another to discover a product's custom options. All requests and responses use application/json and require Authorization: Bearer {token}.

V1
Contract versionStable structure for external integrations.
POST
Atomic creationSale, items and link in a single operation.
16–64
Idempotency-KeyCharacters for safe retries without duplicating the sale.
3
EndpointsCreate the sale, look it up and list options.
The sale total is always calculated by the server from the submitted items. The consumer must not send a total field. Each item's price is the commercial price set by the integration.

Endpoints

Summary of the available contracts. Base URL in the examples: /api2. Every call requires Authorization: Bearer {{token}}.

MethodEndpointUse
POST/api2/vendalinkCreates the sale, its items and the checkout link.
GET/api2/vendalink?id={id}Looks up the sale and its current state.
GET/api2/vendalink/options?sku={sku}&store_id={store_id}Looks up the custom options accepted by a product.

Authentication

Use the Yep REST API OAuth 2.0 flow to generate a token and send it on every call. See OAuth 2.0 for the full flow.

curl -X POST "{{route}}/api2/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id={{client_id}}" \
  -d "client_secret={{client_secret}}" \
  -d "grant_type=client_credentials"
Authorization: Bearer {{token}}
Accept: application/json
Content-Type: application/json

Create sale and link

Creates the sale and all items in a single operation, returning the checkout link. The total is calculated by the server.

POST/api2/vendalink

Creates the personalized sale, its items and the checkout link.

JSONIdempotentNew

Headers

Authorization Required
Bearer {{token}}.
Content-Type Required
application/json.
Idempotency-Key Required
Unique 16 to 64 character identifier used for safe retries. See Idempotency.

Fields

email Required
String. Valid recipient e-mail, up to 150 characters.
store_id Required
Integer. Active store view used for catalog, currency, URL and e-mail.
coupon_code Optional
String. Existing, active coupon code.
send_email Optional
Boolean. When true, requests the e-mail to be scheduled. Default: false.
expires_at Optional
ISO 8601. Future link expiration date.
items Required
Array. List with at least one item.
items[].sku Required
String. SKU existing and enabled for the store.
items[].qty Required
Number. Quantity greater than zero.
items[].price Required
Number. Unit price greater than zero, up to two decimals. It is the commercial price set by the integration.
items[].options Conditional
Object. The key is the option_id and the value depends on the option type. Check the product options before sending.

Request example

curl -X POST "{{route}}/api2/vendalink" \
  -H "Authorization: Bearer {{token}}" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6ec51e29-038d-4dbd-9be9-d6940935f103" \
  -d '{
    "email": "[email protected]",
    "store_id": 1,
    "coupon_code": "WELCOME10",
    "send_email": false,
    "expires_at": "2026-07-23T23:59:59-03:00",
    "items": [
      {
        "sku": "SKU-001",
        "qty": 2,
        "price": 149.90,
        "options": {
          "123": "456",
          "124": "Custom text",
          "125": "2026-07-20",
          "126": "14:30"
        }
      }
    ]
  }'

Response — 201 Created

{
  "success": true,
  "vendalink": {
    "id": 87,
    "status": "pending",
    "email": "[email protected]",
    "store_id": 1,
    "coupon_code": "WELCOME10",
    "total": 299.80,
    "currency": "BRL",
    "checkout_url": "https://store.example.com/vendalink/venda/index/id/TOKEN",
    "expires_at": "2026-07-24T02:59:59+00:00",
    "order_increment_id": null,
    "email_sent": false,
    "created_at": "2026-07-16T19:30:00+00:00",
    "items": [
      {
        "id": 201,
        "sku": "SKU-001",
        "qty": 2,
        "price": 149.90,
        "row_total": 299.80,
        "options": {
          "123": "456",
          "124": "Custom text",
          "125": "2026-07-20",
          "126": "14:30"
        }
      }
    ]
  }
}
If the sale is created but the e-mail cannot be scheduled, the creation is not rolled back. The response will indicate email_sent=false and may include a warnings list. The checkout link must be treated as sensitive data and must not be published in open logs.

Idempotency

The Idempotency-Key ensures that resending the exact same request does not create a second sale. Generate a new key for each new sale and preserve the key when repeating the same operation.

ScenarioResponse
First request with the key201 Created.
Same key and same payload200 OK, original record and idempotent_replay=true.
Same key and different payload409 Conflict.
Missing or invalid key400 Bad Request.

Look up sale

Looks up the created sale. The response uses the same vendalink object returned on creation.

GET/api2/vendalink?id={{vendalink_id}}by ID

Returns the sale and its current state.

curl "{{route}}/api2/vendalink?id={{vendalink_id}}" \
  -H "Authorization: Bearer {{token}}" \
  -H "Accept: application/json"

States

StateMeaning
pendingLink available with no order attached.
convertedOrder created; order_increment_id populated.
expiredDeadline passed without conversion.

Product options

Returns the identifiers and formats required to fill items[].options. Query this endpoint before sending products with custom options.

GET/api2/vendalink/options?sku={{product_sku}}&store_id={{store_id}}

Lists the custom options accepted by a product.

curl "{{route}}/api2/vendalink/options?sku={{product_sku}}&store_id={{store_id}}" \
  -H "Authorization: Bearer {{token}}" \
  -H "Accept: application/json"

Response — 200 OK

{
  "success": true,
  "product": {
    "sku": "SKU-001",
    "name": "Sample product",
    "catalog_price": 159.90,
    "options": [
      {
        "option_id": 123,
        "title": "Color",
        "type": "drop_down",
        "required": true,
        "values": [
          {
            "option_type_id": 456,
            "title": "Blue",
            "price": 0,
            "price_type": "fixed"
          }
        ]
      }
    ]
  }
}
The catalog price returned here is informational; the effective sale value will be the items[].price sent on creation.

Option formats

The value of each key in items[].options depends on the option type returned above.

TypeExpected value
drop_down, radiooption_type_id.
checkbox, multipleArray of option_type_id.
field, areaText.
dateYYYY-MM-DD.
timeHH:mm.
date_timeYYYY-MM-DDTHH:mm.
fileNot supported in V1 JSON.

Integration recommendations

Consolidated best practices for integrations that create personalized sales with the Yep Platform.

Recommended

  • Generate a new Idempotency-Key for each new sale and preserve the key when repeating the exact same operation.
  • Query /api2/vendalink/options before sending products with custom options.
  • Treat the checkout_url as sensitive data — do not publish it in open logs or shared channels.
  • Let the server calculate the total; send only items[].price as each item's commercial price.
  • Check email_sent and the warnings list in the response when using send_email=true.

Avoid

  • Reusing the same Idempotency-Key with a different payload — it returns 409 Conflict.
  • Sending a total field in the body — the total is always calculated by the server.
  • Filling items[].options without first querying the product options endpoint.
  • Using the catalog price as the sale value — the effective value is the items[].price sent.

Recommended flow

Query the product options → build the payload with items[].options in the correct format → send the POST with a fresh Idempotency-Key → deliver the checkout_url to the customer → track the sale state via GET /api2/vendalink?id={id} until converted or expired.

Common errors

StatusWhen it happens
400Invalid JSON, missing field, invalid format or missing idempotency key.
401Missing, invalid, revoked or expired token.
403Token without permission for the resource.
404Sale, SKU, store or coupon not found.
409Idempotency key reused with a different payload.
422Product, option or coupon exists, but the combination cannot create the sale.
500Unexpected technical failure.
{
  "success": false,
  "error": "Objective error description.",
  "field": "items.0.options.123"
}