Docs

Shape your requests

Pagination, filtering, sorting, and field selection on MindCloud API list endpoints.

Every list endpoint shares one query grammar: workflows, workflow runs, run operations, connections, members, roles, companies, environments, API keys, child organizations, Universal API app and action discovery, and Embedded end-user connections. Learn it once and it applies to all of them.

Some endpoints add parameters of their own, and their pages say so:

  • Universal API app discovery also takes q and actionQ; action discovery takes version, q, verbosity, and includeArguments.
  • Universal API lookups page the provider's choices with limit 1 to 200 (default 50) and offset.
  • Workflow versions, run steps, and the usage endpoints return their full result without pagination.

Pagination

Use limit and offset. limit defaults to 100 and accepts 1 to 1000; offset starts at 0. A value outside those ranges returns 400. The response meta.pagination describes where you are:

{
  "meta": {
    "pagination": { "totalCount": 312, "totalCountExact": true, "hasNextPage": true, "hasPreviousPage": true }
  }
}

Page with hasNextPage. totalCount is for display: counting stops at 10,000 rows, and past that totalCount reads 10000 with totalCountExact set to false.

curl "https://connect.mindcloud.co/v2/workflows/Wq3kZ8pLx2Nb/runs?limit=50&offset=100" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"

Lists have a stable default order, with the resource id breaking ties, so pages stay consistent without passing sort.

Sorting

Pass sort with one or more comma-separated fields. Prefix a field with - for descending:

curl "https://connect.mindcloud.co/v2/workflows/Wq3kZ8pLx2Nb/runs?sort=-startedOn" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"

Field selection

Pass fields to receive only the columns you need. id is always included:

curl "https://connect.mindcloud.co/v2/workflows?fields=id,name,isActive" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"

Filtering

Any exposed field filters with plain equality or a bracket operator:

# Equality
curl "https://connect.mindcloud.co/v2/workflows/Wq3kZ8pLx2Nb/runs?status=failed" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"

# Operators
curl "https://connect.mindcloud.co/v2/workflows/Wq3kZ8pLx2Nb/runs?startedOn[gte]=2026-07-01&status[in]=failed,interrupted" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"
OperatorMeaning
eqEquals (same as no operator)
neNot equal
gt, gteGreater than, greater or equal
lt, lteLess than, less or equal
containsSubstring match
starts, endsPrefix or suffix match
in, ninIn or not in a comma-separated list

contains, starts, ends, and =like= are case-insensitive and treat % and _ as plain characters; * is the one wildcard (name[contains]=sync*v2). They apply to text fields only.

Date fields take a date (2026-10-01 or 10/01/2026) or a timestamp (2026-10-01T12:00:00Z), in UTC.

Use only the field names listed on each endpoint's page. A filter, sort, fields entry, or where comparison on a name the endpoint does not expose returns 400 naming the accepted names, and so does a value the field cannot hold, like a date that does not exist. For GET /v2/connections?stauts=valid:

{
  "success": false,
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Cannot filter on \"stauts\". Filterable fields: id, appId, status, isCompany, endUserId, installationId, userId, testedOn, expiresOn, authenticatedOn, createdOn, createdBy, updatedOn.",
    "details": {
      "reason": "UNKNOWN_FILTER_FIELD",
      "field": "stauts",
      "accepted": ["id", "appId", "status", "isCompany", "endUserId", "installationId", "userId", "testedOn", "expiresOn", "authenticatedOn", "createdOn", "createdBy", "updatedOn"]
    }
  }
}

Unknown query parameters and unknown JSON body fields are refused the same way on every endpoint. A few long-standing read endpoints still accept them for now; see Errors.

Advanced filters

For OR conditions and grouping, pass an RSQL expression in where:

curl "https://connect.mindcloud.co/v2/workflows/Wq3kZ8pLx2Nb/runs" \
  --data-urlencode "where=(status==failed,status==interrupted);startedOn>=2026-07-01" -G \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"
SyntaxMeaning
==, !=Equals, not equal
>, >=, <, <=Comparisons
=in=(a,b), =out=(a,b)In or not in a list
=like=Case-insensitive match; * is the wildcard
;AND
,OR
( )Grouping

AND binds tighter than OR, as in the RSQL specification: status==failed,status==interrupted;version==draft means failed runs, or interrupted draft runs. Group with parentheses to say otherwise. where expressions are limited to 2,048 characters and combine with bracket filters using AND.

Rate limits

Each API key gets 240 read requests (GET) and 60 write requests (POST, PUT, DELETE) per minute, in separate budgets. Every response reports where you stand:

HeaderMeaning
X-RateLimit-LimitRequests allowed per minute for this budget
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the window resets

Past the limit, requests return 429 with code RATE_LIMITED and a Retry-After header with the seconds to wait. Back off until then; the budget refills at the reset time.

Errors

Every error uses one envelope. code is one of a small fixed set, decided by the HTTP status; details.reason names the specific cause when there is more to say, and details carries any evidence, such as the accepted values or the workflows that block a delete:

{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "This connection is used by 2 active workflows.",
    "details": { "reason": "CONNECTION_IN_USE", "workflows": [{ "id": "Wq3kZ8pLx2Nb", "name": "Order Sync", "usageCount": 3 }] }
  }
}
StatusCodeMeaning
400VALIDATION_FAILEDA parameter, field, body key, or value the endpoint does not accept
401UNAUTHORIZEDMissing, invalid, or revoked API key
403FORBIDDENThe key cannot do this, for example API_KEY_ACCESS_DENIED or COMPANY_SCOPE_MISMATCH
404NOT_FOUNDThe resource does not exist in your company
409CONFLICTThe resource's state prevents it, for example WORKFLOW_NOT_PUBLISHED or CONNECTION_IN_USE
410GONEThe operation is no longer available
413PAYLOAD_TOO_LARGEThe result is too large to serve, for example RUN_OUTPUT_TOO_LARGE
429RATE_LIMITEDRate limit reached; wait for Retry-After
500INTERNAL_ERRORSomething failed on our side
502PROVIDER_ERRORThe connected app itself refused or failed; details.provider.status is its HTTP status
503UNAVAILABLEA dependency is temporarily unavailable; retry

Branch on code for the kind of failure and on details.reason for the cause. A provider's own status never becomes the response status: a Universal action whose provider answers 404 returns 502 PROVIDER_ERROR with details.provider.status 404. PROVIDER_ERROR only means the app answered; when MindCloud refuses a run before calling the app (a connection for another app, an operation the action does not support), the code is the matching one above with the cause in details.reason.

Run step reads can also return 409 with reason RUN_OUTPUT_UNAVAILABLE when the final log upload is still pending or failed. A finished execution does not guarantee that its final step output is available.

Long-standing read endpoints

These endpoints serve live integrations and keep their earlier behavior until it can change without breaking them: GET /v2/workflows, /v2/workflows/{workflowId}, /v2/workflows/{workflowId}/runs, /v2/workflows/{workflowId}/versions, /v2/runs/{runId}, /v2/runs/{runId}/steps, /v2/usage, /v2/usage/daily, /v2/usage/workflows, and /v2/me. On them:

  • Unknown parameters and names are ignored, an out-of-range limit falls back to 100, and % and _ in contains, starts, and ends act as wildcards.
  • The specific cause is the code itself, with no details: INVALID_QUERY for every 400, NOT_FOUND, RUN_OUTPUT_UNAVAILABLE, USAGE_UNAVAILABLE.

The 401 envelope and the AND-before-OR rule above apply to them too. Send only the names their pages list, and they keep working when they adopt the rest.