For developers
PointLit POS API for developers
Everything a till does, your system can do: read the catalogue, read live stock, place an order, read it back, and take goods back. Read this page once and integrate without asking us a question.
What this API is for
The PointLit partner API lets another system (an ecommerce storefront, a marketplace integration, a warehouse tool) do what a till does: read the catalogue, read live stock, place an order, read it back, and take goods back. Everything happens inside the same authorization model the shop’s own staff work under, so a Business owner grants a machine exactly what they could grant a person, and never more.
There is no second sale path behind it. An order placed here is written by the same code, with the same stock ledger, the same tax engine and the same rounding as an order rung up on the counter.
Every call your token makes is recorded for the Business owner: the route, the status and the timing, never the body or the query string. The request log page says exactly what is kept and for how long.
Quickstart
Put the token in your shell (step 1), then make four calls (steps 2 to 5). Only step 4 writes anything, and it is idempotent.
export POINTLIT_TOKEN="the token the owner gave you"
export POINTLIT_API="https://<workspace>.pointlit.app/api/v1"
auth=(-H "Authorization: Bearer $POINTLIT_TOKEN")curl -s "${auth[@]}" "$POINTLIT_API/products?limit=5"
# {"data":[{"id":"…","name":"Flat white","priceMinor":4500,"currency":"EGP",
# "baseUnit":"pcs","active":true, …}],"nextCursor":"…"}curl -s "${auth[@]}" "$POINTLIT_API/stock?locationId=$LOCATION_ID"
# {"data":[{"variantId":"…","locationId":"…","onHandQty":"12.000000"}],
# "nextCursor":null}curl -s -X POST "${auth[@]}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
"$POINTLIT_API/sales" -d '{
"locationId": "11111111-1111-4111-8111-111111111111",
"lines": [
{
"variantId": "22222222-2222-4222-8222-222222222222",
"quantity": "2"
}
],
"payment": {
"method": "manual_card"
}
}'
# 201 → {"sale":{"id":"…","billNumber":1042,"status":"paid","totalMinor":9000,…},
# "lines":[…],"payments":[…],"refunds":[]}Note what that body does not contain: no price, and no amountMinor. A single payment leg settles whatever the server prices the cart at. amountMinor belongs to a split tender, where “half on the card, the rest in cash” is real information, and because /v1 bodies are strict, sending it on a single leg is a v1_invalid_body rather than a silently ignored field:
{
"locationId": "11111111-1111-4111-8111-111111111111",
"lines": [
{
"variantId": "22222222-2222-4222-8222-222222222222",
"quantity": "2"
}
],
"payments": [
{
"method": "manual_card",
"amountMinor": 5000
},
{
"method": "cash",
"amountMinor": 4000
}
]
}curl -s "${auth[@]}" "$POINTLIT_API/sales/$SALE_ID"$LOCATION_ID is the Location the owner wants online orders fulfilled from. Ask them for it; a token carries no Location, because a machine has no shift and no till to be standing at.