Skip to main content
Salfio Docs

Search documentation

Type to search this documentation.

List a client's assignment rules

GET/clients/{clientId}/assignment-rulesList a client's assignment rules

Returns one entry per active integration in the organization, each carrying that integration's current rule for this client. When an integration has no rule configured for the client yet, the entry is still returned with ruleId: null — so this doubles as a way to discover the integrationIds you can bind.

Cross-tenant lookups and missing clients both return 404 not_found so existence is never leaked.

Parameters

clientIdstring · uuidpathrequired

Client UUID.

Responses

200The client's assignment rules.application/json

Headers

X-RateLimit-Limit

The request cap for the tighter of the per-organization / per-endpoint windows that applied to this request.

X-RateLimit-Remaining

Requests remaining in the current window.

X-RateLimit-Reset

Unix timestamp (seconds) when the current window resets.

value
allOf · 2 options
Option 1objectEnvelope
datavaluerequired

The response payload — shape depends on the endpoint.

metaobjectrequired

Pagination metadata — populated on list endpoints, empty on single-resource endpoints.

Show child attributes
cursornull | string

Opaque cursor to pass to the next request.

hasMoreboolean | null

True when further pages of results are available.

Option 2object
dataarray of object
Show child attributes
Show array items

A client's assignment rule for a single integration. One is returned per active integration; `ruleId` and the other rule fields are `null` when no rule is configured for the client on that integration yet.

chatLabelsobject

Only on read-only WhatsApp entries — maps the chat JIDs referenced by `filterCriteria` to display names taken from synced conversations. A ruled chat that never synced a message has no entry.

createdAtnull | string · date-timerequired

UTC timestamp when the rule was created (`null` when none is set).

enabledbooleanrequired

Whether the rule is active.

filterCriteriavaluerequired
Show child attributes
anyOf · 2 options
Option 1value

The rich querybuilder criteria deciding which of the integration's communications are assigned to the client; `null` when no rule is set. For Slack, a channel binding looks like `{"condition":"or","rules":[{"field":"channel","operator":"equals","value":"general"}]}`.

Option 2nullnullable
integrationIdstring · uuidrequired

The integration this rule binds to the client. Pass it back in a PUT to configure the rule.

integrationTypestringrequired

Provider of the bound integration (e.g. `slack`, `gmail`).

priorityintegerrequired

Rule ordering (lower number = higher priority).

providerEmailstringrequired

The account/email the integration authenticates as.

readOnlyboolean

The caller may not write this rule — the integration is configurable only by the user who connected it (WhatsApp). Never include a read-only entry in a PUT replacement set; writing one is rejected. User-authenticated callers still see the rule's real values; callers with no user identity additionally get `rulesHidden: true` with the rule fields withheld.

ruleIdnull | string · uuidrequired

Stable UUID of the rule, or `null` when none is configured yet.

rulesHiddenboolean

The rule was withheld entirely because the caller carries no user identity (org-scoped service keys): `ruleId` and `filterCriteria` are `null` and `enabled` is `false` regardless of what is configured — do not read such an entry as "no rule yet". Deprecated as the do-not-write signal in favor of `readOnly`, which also covers user-authenticated callers.

updatedAtnull | string · date-timerequired

UTC timestamp of the most recent rule update (`null` when none is set).

Example response
{
  "data": [
    {
      "chatLabels": {
        "additionalProp1": "string"
      },
      "createdAt": "2026-06-09T00:00:00Z",
      "enabled": true,
      "filterCriteria": null,
      "integrationId": "00000000-0000-0000-0000-000000000000",
      "integrationType": "slack",
      "priority": 0,
      "providerEmail": "string",
      "readOnly": true,
      "ruleId": "00000000-0000-0000-0000-000000000000",
      "rulesHidden": true,
      "updatedAt": "2026-06-09T00:00:00Z"
    }
  ],
  "meta": {
    "cursor": "string",
    "hasMore": true
  }
}
400Request body / query parameters failed validation.application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "invalid_argument",
    "message": "limit must be an integer between 1 and 100"
  }
}
401Missing or invalid bearer token. The message is intentionally opaque — do not rely on it to distinguish "missing" from "invalid".application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "unauthorized",
    "message": "Authentication required"
  }
}
404The referenced resource does not exist, or belongs to a different organization than the one owning the API key. The public API does not distinguish between these cases — both return 404 to avoid leaking cross-tenant existence. application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "not_found",
    "message": "client not found"
  }
}
429Per-organization or per-endpoint rate limit exceeded.application/json

Headers

Retry-After

Seconds the client should wait before retrying.

objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "rate_limited",
    "details": {
      "retry_after_seconds": 30
    },
    "message": "Rate limit exceeded"
  }
}

Documentation menu