Connect Zapier or n8n
Any tool that can send an HTTP request can use the API. Set the step up like this:
- Method and URL: e.g.
POSTandhttps://serveu-psi.vercel.app/api/v1/cards/lookup. - Header
Authorization: Bearer serveu_live_XXXX…, kept in the tool's credentials when it has them (in n8n, a Header Auth credential), never typed into a step's visible text. - Header
Content-Type: application/jsonand a JSON body. - Header
Idempotency-Keybuilt from the trigger's own id (a row id, a form submission id), so a re-run of the same trigger never adds stamps twice.
Example: a row added to Google Sheets adds stamps
- Trigger: new row with a phone number and a receipt number.
- Find the card:
POST https://serveu-psi.vercel.app/api/v1/cards/lookup
Authorization: Bearer serveu_live_XXXX…
Content-Type: application/json
{"phone":"{{row.phone}}"}- Add the stamps with the card's
idfrom the answer:
POST https://serveu-psi.vercel.app/api/v1/cards/{{lookup.id}}/earn
Authorization: Bearer serveu_live_XXXX…
Content-Type: application/json
Idempotency-Key: sheet-row-{{row.id}}
{"stamps":1,"reference":"{{row.receipt}}"}The key needs Give stamps and points. A 404 on the lookup means the phone has no card yet: stop there, or add a step that joins the customer (POST /api/v1/cards).
Example: post yesterday's sales to Slack every morning
- Trigger: a schedule, every day at 07:00 Riyadh time, once yesterday is over.
- Get yesterday's summary:
fromandtoare both yesterday's date (dates are in the business's time zone and both are included). On 9 November:
GET https://serveu-psi.vercel.app/api/v1/orders/summary?from=2026-11-08&to=2026-11-08
Authorization: Bearer serveu_live_XXXX…- Post a message with
ordersandsales. Amounts are in halalas: divide by 100 for SAR.
The key needs See orders and sales (orders:read).
To start a Zap or workflow when something happens in ServeU (a new order, a stamp added), use webhooks: see the next section.
Trigger a Zap or workflow from ServeU
- Create the trigger: in Zapier a Webhooks by Zapier "Catch Hook", in n8n a Webhook trigger node set to
POST(use its production URL and activate the workflow). Copy itshttps://URL. - Ask the owner to add it in Settings → Developers → Webhooks with the events you need (or create it with the API: see Webhooks).
- Press Send test event, then a real one (place a test order, add a stamp) so the tool can map fields such as
data.object.numberordata.object.balance. The test event is aping: filter it out (a step that continues only whentypeisn'tping).
These tools don't check Standard Webhooks signatures by themselves, so anyone who learns the URL could trigger the workflow:
- Keep the hook URL as secret as a key, and give each workflow its own.
- In n8n, you can verify in a Code node. It needs the body exactly as it arrived (turn on the Webhook node's raw body option) and the function below — the same as the Node sample in Webhooks, written with
requireas Code nodes need. On self-hosted n8n, allow the module withNODE_FUNCTION_ALLOW_BUILTIN=crypto. Option names differ between n8n versions; check n8n's own docs if yours don't match. Stop the workflow when it returnsfalse. - Don't turn on Include contact details for a Zapier or n8n endpoint unless the workflow needs the customer's name and phone: each run's data is kept in the tool's history.
const { createHmac, timingSafeEqual } = require("crypto");
function verifyServeU(rawBody, headers, secret) {
const id = headers["webhook-id"], ts = headers["webhook-timestamp"], sigs = headers["webhook-signature"];
if (!id || !ts || !sigs || !/^\d+$/.test(ts)) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // 5 minutes
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = Buffer.from(createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest("base64"));
return sigs.split(" ").some((s) => {
const [version, value] = s.split(",");
const got = Buffer.from(value ?? "");
return version === "v1" && got.length === expected.length && timingSafeEqual(got, expected);
});
}
For a regular schedule instead (a report every morning), poll a list: see Pagination, filtering & sync.