Search

Search guides and the API reference

Get started

Overview

What the On Me API does, how a gift moves from order to recipient, and the core concepts every integration uses.

For AI agents: this page is available as Markdown, and every guide plus the API reference is in llms-full.txt.

The On Me API lets your platform buy and send On Me gifts from your own code. You pick a category, choose an amount and a way to deliver it, and we take care of the rest: the gift reaches your recipient, they claim it, and they get a virtual card they can spend at that category's merchants.

Every gift is paid for from your organization's On Me balance, so there are no cards to charge and no checkout to build.

What you can do

  • Browse the catalog. List every gift category with GET /v1/categories.
  • Send gifts. Create an order of 1 to 10 gifts with POST /v1/orders. The whole order is paid for in one debit from your balance.
  • Deliver them your way. We can email or text each gift for you, or hand you a link to share however you like.
  • Track what happens next. Read orders and gifts back to see whether each one was sent, opened, claimed or failed.
  • Fix a failed delivery. Point an undelivered email or text gift at a new address with PUT /v1/gifts/{gift_id}/delivery.

Core concepts

  • Category: what the gift is for, such as Coffee or Dining. The category decides where the recipient's card can be spent. You pass its id when you create a gift. Some categories, like Choice, let the recipient pick a category when they claim.
  • Order: one purchase of 1 to 10 gifts, created with a single request and paid for with a single debit from your balance. Order IDs look like o-….
  • Gift: one gift for one recipient, with an amount, a category, a delivery method and, optionally, the names the recipient sees. Gift IDs look like g-…. Every gift belongs to exactly one order.
  • Recipient: the person who receives the gift. They don't need an On Me account to receive it; they sign in or create one when they claim it.
  • Balance: your organization's prepaid funds. You top it up in the business portal under Billing, and each order draws it down by the order's total.

How a gift moves

How a gift moves through the On Me APIFund balance → POST /v1/orders → Gifts created → Delivered (email, SMS or link) → Recipient claims → Card issued. Delivery status moves sent → opened → claimed, or failed.Fund balancePOST/v1/ordersGifts createdDeliveredemail, SMS or linkRecipient claimsCard issuedfailedsentopenedclaimed

Fund your balance. Add funds in the business portal. Your balance must cover an order's full total before we accept it.

Create an order. POST /v1/orders debits your balance and creates every gift in the order before it responds. Either the whole order goes through, or nothing happens. In rare cases we hit a problem after the debit: the order then comes back as processing, possibly with gifts: [], and its gifts are finished shortly after. See when the status is processing.

We deliver each gift. Email and SMS gifts go out straight away. Link gifts come back with a delivery.link URL for you to share.

The recipient opens and claims it. They open the gift, see who it's from, and claim it to their On Me account.

We issue the card. Claiming issues a virtual card that works at the category's merchants, or adds the funds to a card they already hold for that category.

You can follow each gift through delivery.status:

delivery.statusWhat it means
sentWe sent the email or text, or created the link. This is where every gift starts.
openedThe recipient opened the gift.
claimedThe recipient claimed the gift and has a card to spend it on.
failedWe couldn't deliver the email or text. You can send it somewhere else.

The status always shows the furthest point a gift has reached. A gift that failed, was re-sent and then claimed reads claimed.

Requests and responses

Every request goes to https://api.onme.com, over HTTPS, and every path starts with /v1. Send request bodies as JSON with Content-Type: application/json; bodies are limited to 1 MB. Responses are always JSON.

Responses come in three shapes. There is no wrapper around them: what you see below is the entire body.

A single resource comes back as the object itself:

200GET /v1/orders/{order_id}
{
  "order_id": "o-bc1KeWwb90nw_0Jfspeu_oNs0EM7XcAKLQKS64QdQIo",
  "status": "processed",
  "gifts": [
    {
      "gift_id": "g-Q5-Vef_a-vnAqGgTVfBArnb8sjHOBCjz7Z7nm4Udlww",
      "amount": 2500,
      "category": "coffee",
      "delivery": { "method": "email", "status": "sent", "email": "sam@example.com" },
      "personalization": { "recipient_name": "Sam", "sender_name": "Acme" }
    }
  ]
}

A list comes back in a list object, with the items in data:

200GET /v1/gifts?limit=1
{
  "object": "list",
  "data": [
    {
      "gift_id": "g-Q5-Vef_a-vnAqGgTVfBArnb8sjHOBCjz7Z7nm4Udlww",
      "amount": 2500,
      "category": "coffee",
      "delivery": { "method": "email", "status": "opened", "email": "sam@example.com" },
      "personalization": { "recipient_name": "Sam", "sender_name": "Acme" }
    }
  ],
  "has_more": true
}

An error comes back as a single error object, with a non-2xx status:

422Unprocessable Entity
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "Invalid email address",
    "param": "gifts[0].delivery.email",
    "doc_url": "https://business.onme.com/docs/reference#errors/parameter_invalid",
    "request_id": "req-C4451Fpu_emD-fIdoqAQ8dKd9HqnoBiJUf-EvRdz0qM"
  }
}

Branch on type and code, never on message: the message is written for people and can change. When the error is about one field, param names it. Every code has its own entry in the error reference, which doc_url links to directly.

Conventions

Amounts

Amounts are integers in US cents. 2500 is $25.00. A gift can be worth between 1000 ($10) and 50000 ($500).

IDs

IDs are opaque strings with a prefix that tells you what they are:

PrefixIdentifies
o-An order
g-A gift
req-A single API request

Treat everything after the prefix as opaque: don't parse it or rely on its length. Category IDs are strings such as coffee.

Pagination

GET /v1/orders and GET /v1/gifts return results newest first, one page at a time. They take three query parameters:

ParameterDescription
limitPage size, from 1 to 100. Defaults to 10.
starting_afterAn ID from the current page. Returns the page after it.
ending_beforeAn ID from the current page. Returns the page before it.

Send starting_after or ending_before, not both. When has_more is true, pass the last item's ID as starting_after to get the next page:

curl "https://api.onme.com/v1/orders?limit=25&starting_after=o-bc1KeWwb90nw_0Jfspeu_oNs0EM7XcAKLQKS64QdQIo" \
  -H "Authorization: Bearer $ONME_API_KEY"

A cursor that doesn't match one of your orders or gifts returns cursor_invalid. GET /v1/categories returns the whole catalog in one response, so its has_more is always false.

Request IDs

Every response, success or error, carries a Request-Id header, such as req-C4451Fpu_emD-fIdoqAQ8dKd9HqnoBiJUf-EvRdz0qM. Error bodies repeat it as request_id. Log it alongside your own records, and include it when you contact support@onme.com so we can find the exact request.

Rate limits

Limits apply per API key, over a 60-second window:

ScopeLimit
All endpoints120 requests per minute
POST /v1/orders30 requests per minute, which also count toward the 120

A separate limit of 300 requests per minute per IP address covers all traffic, including requests without a valid key.

Every response tells you where you stand, using the IETF RateLimit headers:

RateLimit-Policy: 120;w=60
RateLimit: limit=120, remaining=117, reset=42

remaining is how many requests you have left in the window, and reset is the number of seconds until it resets. Responses from POST /v1/orders report its tighter limit. Go over a limit and you get a 429 with the rate_limit_exceeded code and a Retry-After header. Wait that many seconds, then retry.

Compatibility

While the API is in beta, any part of it can change, including in ways that break working integrations. We also add things without notice: new fields on responses, new endpoints, new optional parameters and new error codes. Build your integration so it ignores fields it doesn't recognize and handles a value it hasn't seen before, such as a new delivery.status, without crashing. If a change breaks your integration, email support@onme.com.

Next steps