Developers
REST API
Endpoints, pagination, errors and conventions.
Make a request
The REST API starts at https://app.systemly.com.au/api/v1 on the hosted app. Send an API key as an Authorization bearer token. The key selects its workspace; no workspace ID is needed in the URL or request body. Create a key under Settings → Developer tools → API keys first.
curl "https://app.systemly.com.au/api/v1/contacts?page=1&perPage=25" \
-H "Authorization: Bearer $SYSTEMLY_API_KEY"Keep the key in a secret manager or environment variable, not source control or browser-side code. See Authentication.
Available endpoints
GET, POST /contactsList or create contacts.
GET, PATCH, DELETE /contacts/:idRead, update, or delete one contact.
GET, POST /opportunitiesList or create pipeline opportunities.
GET /formsList forms.
GET /workflowsList automations.
GET, POST /social/postsList posts or create a draft or schedule. Immediate publishing is not available through this API.
GET /appointmentsList appointments in a date range.
GET, POST /mediaList generated images and videos, or make one. Send kind as IMAGE (with prompt, aspect, count) or VIDEO (with prompt, seconds of 4, 8 or 12, aspect). Add useBrand: true to apply the workspace's brand kit. An image returns finished with 201; a video returns at once with 202 and an id to poll. Needs the AI generation permission, and returns 409 if no OpenAI or OpenRouter key or AI usage are available.
GET /media/:idRead one generation. Polling a video in progress also checks on the render, so its status moves to COMPLETED with a url, or to FAILED with an error.
Write requests use JSON and Content-Type: application/json. For example, creating a contact requires firstName:
curl -X POST "https://app.systemly.com.au/api/v1/contacts" \
-H "Authorization: Bearer $SYSTEMLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"firstName":"Jordan","email":"jordan@example.com"}'Filter and page through lists
- Contacts use page and perPage. Defaults are 1 and 25; perPage accepts 10 to 100. The response includes page, perPage, total, and totalPages.
- Contact filters are q, status, tagId, and assignedToId.
- Opportunities use limit and offset, defaulting to 50 and 0 with a maximum limit of 200. The response includes limit, offset, and total. You can filter by status and pipelineId.
- Appointments accept optional from and to dates and return up to 200 records. Social posts accept a status filter and return up to 100.
List and detail responses put records under data. Only the contacts and opportunities lists add a pagination object. A successful create returns HTTP 201. Amount fields such as opportunityvalueCents are integer minor currency units, not decimal dollars.
Handle errors
Errors are JSON with an error message. Validation failures return HTTP 422 with field details; application errors may also include a machine-readable code. Expect 401 for a missing, invalid, or expired key; 403 for a missing scope; 404 for a record outside the key's workspace; and 429 when a rate limit is reached. Do not assume every error has identical fields. See Rate limits for retry behavior.
