Flows API
REST endpoints for programmatic access to your flows, runs, and connectors. All requests use JSON and respect the same permissions as your APIXX account.
https://api.apixx.io/v1Authentication
All requests require a bearer token. Generate keys from the Settings → API keys page. Keys are scoped to your customer and inherit the roles of the user that created them.
Authorization: Bearer apx_live_••••••••
Content-Type: application/json- Treat keys like passwords — store them in your secret manager, never in client code.
- Rotate keys with
POST /api-keys/:id/rotateor by deleting and re-creating. - Test keys are prefixed
apx_test_; live keys areapx_live_.
Endpoints
Flows
| GET | /flows | List all flows for the current customer. |
| GET | /flows/:id | Retrieve a single flow with connector + schedule details. |
| POST | /flows/:id/pause | Pause a flow. Returns the updated flow. |
| POST | /flows/:id/resume | Resume a paused flow. |
| POST | /flows/:id/trigger | Manually trigger a run. Returns the new run id. |
Runs
| GET | /runs | List runs. Filter via ?flow_id=, ?status=, ?from=, ?to=. |
| GET | /runs/:id | Retrieve a run with records processed, duration, and errors. |
| POST | /runs/:id/retry | Retry a failed run. Returns the new run id. |
Connectors
| GET | /connectors | List connected systems and their current status. |
| GET | /connectors/:id | Retrieve a single connector. |
| POST | /connectors/:id/verify | Test the credentialed link. Returns ok / error. |
APIXX Data — Canonical Read API
Pull normalized, deduplicated records from the canonical data layer. Endpoints are scoped to the API key's tenant and require the data:read scope. The base path is /api/public/data (this app's origin), not https://api.apixx.io/v1.
| GET | /api/public/data/:entity | List canonical records. Supports ?limit, ?cursor, ?updated_since, ?fields. |
| GET | /api/public/data/:entity/:id | Retrieve a single canonical record by canonical_id. |
:entity ∈ customer, contact, account, lead, opportunity, product, product_variant, order, order_line_item, invoice, payment, subscription, refund, shipment, inventory.
curl 'https://app.apixx.ai/api/public/data/order?limit=50&updated_since=2026-06-01T00:00:00Z' \
-H "Authorization: Bearer apixx_••••••••"{
"entity": "order",
"count": 50,
"next_cursor": "2026-06-12T18:21:04.512Z",
"data": [
{
"canonical_id": "5f0d3a7e-2c6b-4f31-9c3d-1a4e5b6c7d80",
"order_number": "1042",
"status": "paid",
"total_cents": 12450,
"currency": "USD",
"placed_at": "2026-06-12T18:20:11Z",
"external_ids": { "shopify": "gid://shopify/Order/1042" },
"last_source_update_at": "2026-06-12T18:21:04Z",
"updated_at": "2026-06-12T18:21:04.512Z"
}
]
}Paginate by passing the response's next_cursor as the next request's ?cursor. When next_cursor is null you've reached the end of the result set.
Example request
curl https://api.apixx.io/v1/flows \
-H "Authorization: Bearer apx_live_••••••••"{
"data": [
{
"id": "flw_8sJk2",
"name": "Shopify → NetSuite Orders",
"status": "active",
"source": "shopify",
"destination": "netsuite",
"schedule": "every_15m",
"last_run_at": "2026-06-10T19:42:11Z"
}
],
"meta": { "total": 1, "has_more": false }
}Webhooks
Subscribe to events to receive HTTP callbacks instead of polling. Configure endpoints under Settings → Webhooks. APIXX sends a POST with a JSON body and these headers:
X-Apixx-Event: run.failed
X-Apixx-Delivery: del_4nQ2k
X-Apixx-Signature: t=1781119222,v1=8f4a2c...Events
| run.started | — | Fired when a run begins. |
| run.succeeded | — | Fired when a run completes with zero record errors. |
| run.partial | — | Completed, but some records failed. |
| run.failed | — | Run aborted before completing. |
| connector.degraded | — | A connector started returning auth or quota errors. |
| flow.paused | — | A flow was paused via API or UI. |
Signature verification
Compute HMAC-SHA256(secret, timestamp + "." + raw_body) and compare using a timing-safe equality check. Reject deliveries older than 5 minutes.
import { createHmac, timingSafeEqual } from "crypto";
function verify(req, secret) {
const header = req.headers["x-apixx-signature"];
const [tPart, sigPart] = header.split(",");
const timestamp = tPart.slice(2);
const signature = sigPart.slice(3);
const expected = createHmac("sha256", secret)
.update(timestamp + "." + req.rawBody)
.digest("hex");
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}Retries
Non-2xx responses are retried with exponential backoff for up to 24 hours. Return 2xx as soon as the payload is persisted; do downstream work asynchronously.
Rate limits
The API uses a sliding-window limiter per API key:
| Read endpoints | GET | 600 requests / minute |
| Write endpoints | POST · PATCH · DELETE | 120 requests / minute |
| Trigger endpoints | POST /flows/:id/trigger | 60 requests / minute |
Every response includes:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1781119282Exceeding the limit returns 429 Too Many Requests with a Retry-After header (seconds).
Errors
Errors use standard HTTP status codes and a consistent JSON body:
{
"error": {
"code": "flow_not_found",
"message": "No flow with id 'flw_xyz'.",
"request_id": "req_2k9Lz"
}
}| 400 | invalid_request | Malformed JSON or missing required field. |
| 401 | unauthorized | Missing or invalid bearer token. |
| 403 | forbidden | Token lacks permission for this resource. |
| 404 | not_found | Resource does not exist or is not visible to you. |
| 409 | conflict | Resource is in a state that conflicts with the request. |
| 422 | validation_error | Input failed validation. See `message`. |
| 429 | rate_limited | Too many requests. Honor `Retry-After`. |
| 5xx | internal_error | Transient — safe to retry with backoff. |
Always log the request_id — APIXX support can use it to trace your call end-to-end.
Versioning
The current stable version is v1, encoded in the URL path. Breaking changes ship under a new major version with at least 6 months of overlap. Additive changes (new fields, new endpoints) may roll out under v1 at any time — design clients to ignore unknown fields.
