Verinode Developer
Reading data
Pull your jobs, vendors, and clients, and keep them in sync.
GET /v1/jobs, /v1/vendors, and /v1/clients return your records, cursor-paginated, each enum value paired with a humanized _label, money as decimal strings, client contact fields decrypted. Requires read. Reads are free. List endpoints allow 600 calls/hour.
curl -H "Authorization: Bearer $KEY" "https://api.verinode.ai/v1/jobs?limit=25"
→ { "data": [ { "id": "…", "status": "open", "status_label": "Open",
"financials": { "rcv_total": "18450.00" }, "source": "api" } ],
"next_cursor": "…", "has_more": true, "synced_through": null }
#One record by id
GET /v1/jobs/{id}, /v1/vendors/{id}, and /v1/clients/{id} return a single record, serialized identically to its list row. The id from a POST response or a webhook resolves here. 1,000 calls/hour.
A record that doesn't exist and one owned by another operator return the same 404. That's deliberate and won't change: a distinguishable response would let anyone walk ids and learn which ones are real rows in someone else's account.
#Incremental sync
Three rules keep your own system in step, and they compose:
- Page with
cursor, never an offset. The cursor is a keyset over(updated_at, id)— a total order, so pages stay correct even while rows are being written. Passnext_cursorback verbatim; don't parse or build one. - Store
synced_through, pass it back asupdated_since. It is non-null only on the last page (has_more: false). Committing it earlier would skip everything still queued behind the cursor. - Upsert by
id. Sync is at-least-once: a row edited mid-pagination gets a newupdated_at, moving it ahead of your cursor so it arrives again on a later page rather than being skipped. Duplicates are expected and harmless; dropped rows would not be.
# First run: drain every page, then keep synced_through.
curl -H "Authorization: Bearer $KEY" "https://api.verinode.ai/v1/jobs?limit=100"
# → follow ?cursor=<next_cursor> until has_more is false
# Every run after: only what changed.
curl -H "Authorization: Bearer $KEY" \
"https://api.verinode.ai/v1/jobs?limit=100&updated_since=2026-07-17T09:30:00Z"
updated_since is inclusive, so a row sharing the exact boundary instant is re-delivered rather than lost — overlap is free when you upsert, a gap is silent data loss. created_after is also available (exclusive, on created_at) for a one-off window of new records; for sync prefer updated_since, since created_after never shows you an edit to a record you already have.
Prefer push over poll where you can: register a webhook endpoint. For everything at once, use full-account export.