Appearance
Overview
NOMA Sync exposes:
- Public:
GET /health - Webhooks (internal):
POST /webhooks/givebutter,POST /webhooks/square,POST /webhooks/mailchimp— do not call directly; used by Givebutter, Square, and Mailchimp - Admin API: All
/api/*routes require JWT (Authorization: Bearer <token>). Roles: viewer (read-only), admin, super_admin
Base URL example: https://nomasync.21ads.workers.dev or https://noma.21adsmedia.io/.
Public
GET /health
Returns 200 and {"status":"ok"} when the Worker is running. Does not check LGL or third-party APIs.
Webhooks (Internal)
Configure these URLs in each platform; do not call them manually.
| Endpoint | Source | Auth |
|---|---|---|
POST /webhooks/givebutter | Givebutter | Signature (if configured) |
POST /webhooks/square | Square | HMAC in header (SQUARE_WEBHOOK_SIGNATURE_KEY) |
POST /webhooks/mailchimp | Mailchimp | Secret (if configured) |
See Webhooks for payload shapes.
Admin API (Authenticated)
All require Authorization: Bearer <JWT>. Role requirements noted below.
Sync log
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/syncs | viewer+ | List syncs; query: status, source, date_from, date_to, page, limit, sort, order, q |
| GET | /api/syncs/:id | viewer+ | Single sync by UUID (detail modal) |
| PATCH | /api/syncs/:id/resolve | admin+ | Mark sync resolved; body: { notes?, resolvedBy? } |
Stats
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/stats | viewer+ | Aggregate stats (e.g. 24h: total, success, failed) for dashboard |
Settings
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/settings/lgl-environment | admin+ | Current LGL environment (production/sandbox) |
| PATCH | /api/settings/lgl-environment | admin+ | Set LGL environment; body: { environment } |
| POST | /api/settings/lgl-reference-refresh | admin+ | Refresh LGL funds/campaigns/gift-types/payment-types cache |
| GET | /api/settings/alert-recipients | admin+ | List alert recipient emails |
| PATCH | /api/settings/alert-recipients | admin+ | Set alert recipients; body: { emails: string[] } |
| GET | /api/settings/mailchimp-sync-enabled | admin+ | Whether Mailchimp sync is enabled |
| PATCH | /api/settings/mailchimp-sync-enabled | admin+ | Enable/disable Mailchimp sync; body: { enabled: boolean } |
| GET | /api/settings/square-default-constituent | admin+ | Default constituent for Square orders with no customer |
| PATCH | /api/settings/square-default-constituent | admin+ | Set default; body: { email, first_name, last_name } |
Users (Teams)
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/users | super_admin | List users (for Teams page) |
| POST | /api/users/invite | super_admin | Invite user by email; body: { email, role? } |
| PATCH | /api/users/:id | super_admin | Update user (role, deactivate) |
Mappings
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/mappings/types | admin+ | Type defaults (Givebutter, Square) |
| GET | /api/mappings/overrides | admin+ | Campaign overrides (Givebutter) |
| POST | /api/mappings/overrides | admin+ | Create/update override; body per dashboard |
LGL reference (for dropdowns)
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/lgl/funds | admin+ | List LGL funds |
| GET | /api/lgl/campaigns | admin+ | List LGL campaigns |
| GET | /api/lgl/gift-types | admin+ | List LGL gift types |
| GET | /api/lgl/gift-categories | admin+ | List LGL gift categories |
| GET | /api/lgl/payment-types | admin+ | List LGL payment types |
Square
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/square/locations | admin+ | List Square locations |
| GET | /api/square/orders | admin+ | List Square orders; query: cursor, limit |
| POST | /api/square/orders/enrich | admin+ | Enrich customer for given order IDs; body: { orderIds: string[] } |
| GET | /api/square/location-overrides | admin+ | List location → LGL overrides |
| PUT | /api/square/location-overrides | admin+ | Set location overrides; body: array of { location_id, fund_id?, campaign_id? } |
| POST | /api/square/orders/:orderId/resync | admin+ | Resync one order to LGL; query: force=true to skip idempotency |
Givebutter
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/givebutter/campaigns | admin+ | List Givebutter campaigns (cached) |
| POST | /api/givebutter/campaigns/refresh | admin+ | Refresh Givebutter campaign cache |
Mailchimp
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/mailchimp/account | admin+ | Mailchimp account info (test) |
| GET | /api/mailchimp/lists | admin+ | List Mailchimp lists |
| GET | /api/mailchimp/mappings | admin+ | List Mailchimp list mappings |
| POST | /api/mailchimp/mappings | admin+ | Create/update list mapping |
| POST | /api/mailchimp/test | admin+ | Test Mailchimp connection |
| GET | /api/mailchimp/tag-rules | admin+ | List tag rules |
| POST | /api/mailchimp/tag-rules | admin+ | Create/update tag rules |
Testing / dev
| Method | Path | Role | Description |
|---|---|---|---|
| GET | /api/test-connections | admin+ | Test LGL, Givebutter, Square connectivity |
| POST | /api/poll-now | admin+ | Trigger polling job now |
| POST | /api/dev/poll-now | admin+ | Same (dev) |
| POST | /api/poll-fresh | admin+ | Poll with fresh lookback |
| POST | /api/inject-webhook | admin+ | Inject test webhook; body: payload |
| POST | /api/retry-all | admin+ | Retry all failed syncs (use with care) |
| POST | /api/retry-all-fresh | admin+ | Retry with fresh fetch |
| POST | /api/reset-test-data | admin+ | Reset test data (dev only) |
| POST | /api/dev/poll-cron | admin+ | Bypass cron auth (dev only) |
Example: Resync Square order
bash
curl -X POST "https://your-worker.workers.dev/api/square/orders/ORDER_ID/resync" \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json"With force (bypass idempotency):
bash
curl -X POST "https://your-worker.workers.dev/api/square/orders/ORDER_ID/resync?force=true" \
-H "Authorization: Bearer YOUR_JWT"For webhook payload details see Webhooks. For LGL data shapes see LGL Data.

