Bank rule exclusions
An exclusion (bank_rule_exclusion) takes one company out of one workspace rule's reach. It is the workspace scope's safety valve: a rule that suits every company but two need not be duplicated, it is enough to exclude those two.
The rules themselves, their condition vocabulary and their simulation are described on their own page (Bank imputation rules).
Only a workspace rule can be excluded
A company rule can never be the subject of an exclusion. It already concerns exactly one company, so excluding that company from it would be either a no-op or a contradiction. The attempt is refused with a 422, it is not silently ignored. That is also why a company rule's excluded_company_ids is always empty: the empty array is the true answer there, not a filler.
The company you exclude must belong to the rule's workspace. A company of another workspace and a company that does not exist receive the same answer, so this endpoint cannot be used to probe for a company's existence.
Removing an exclusion puts the workspace rule back in force for that company from the next classification on. Neither adding nor removing one rewrites anything already posted: an exclusion owns neither an accounting entry nor a payment.
The endpoints
GET /api/v1/bank_rules/{bank_rule_id}/exclusions- list a rule's exclusionsPOST /api/v1/bank_rules/{bank_rule_id}/exclusions- exclude a company from a ruleDELETE /api/v1/bank_rule_exclusions/{id}- remove an exclusion
Two path shapes, and that is not an inconsistency. The list and the creation are the rule's collection, so they hang off the rule. The removal is addressed by the exclusion's own id, on a path that carries neither the rule nor the company - it is the workspace_id published on the exclusion that authorizes it. None of the three paths carries a workspace_id: it is derived from the rule for the first two, from the exclusion for the third.
Reads require the read scope, the creation the write scope, the removal the destroy or the write scope. The Idempotency-Key header is accepted and optional on both writes.
An exclusion's fields
Six fields, all present in every response. There is nothing more to read: the rule is what carries the overview.
| Field | What it carries |
|---|---|
id | The exclusion's id, the one DELETE /api/v1/bank_rule_exclusions/{id} carries |
workspace_id | The workspace the exclusion belongs to |
bank_rule_id | The workspace rule this company is taken out of |
company_id | The company taken out. It belongs to the rule's workspace |
created_at, updated_at | ISO 8601 timestamps |
The same set is published on the rule, under excluded_company_ids, and that is often all you need. This resource is for when you need each exclusion's own id in order to remove it.
Excluding a company
curl -X POST https://app.scribee.tech/api/v1/bank_rules/88/exclusions \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: b3d7e510-2c48-4a9f-8e61-70f4a2c9d183" \
-d '{ "company_id": 34 }'
{
"data": {
"id": 410,
"workspace_id": 12,
"bank_rule_id": 88,
"company_id": 34,
"created_at": "2026-08-21T15:10:00+02:00",
"updated_at": "2026-08-21T15:10:00+02:00"
}
}
company_id is the body's only field, and it is required. A body carrying none is refused with a 422 and the validation_failed code, naming company.
On a company rule, the refusal names the rule and carries the remedy:
{
"error": "unprocessable_entity",
"code": "validation_failed",
"message": "La validation a échoué",
"details": {
"rule": ["est une règle de société : elle ne concerne déjà qu'une seule société et ne peut pas faire l'objet d'une exclusion"]
}
}
A company outside the rule's workspace - or one that exists nowhere - carries a different code, because what is at fault is not the rule but the field's value:
{
"error": "unprocessable_entity",
"code": "invalid_argument",
"message": "La validation a échoué",
"details": {
"company": ["est introuvable dans l'espace de travail de cette règle"]
}
}
A company already excluded from this rule is refused with a 422 and the validation_failed code, naming company: adding the same exclusion twice produces no duplicate.
Listing a rule's exclusions
curl "https://app.scribee.tech/api/v1/bank_rules/88/exclusions?company_id=34" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": [
{
"id": 410,
"workspace_id": 12,
"bank_rule_id": 88,
"company_id": 34,
"created_at": "2026-08-21T15:10:00+02:00",
"updated_at": "2026-08-21T15:10:00+02:00"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total_pages": 1,
"total_count": 1
}
}
The list is returned by ascending company_id then ascending id, and the data + meta envelope follows API conventions. Pagination is offset-based, with page and per_page - 20 by default, 100 at most.
company_id is the only filter, it is optional, and it expects an integer. A value that is not an integer matches nothing - a 200 with an empty collection, never a 422. An absent or empty parameter is not a filter: it restricts nothing.
The same call on a company rule answers a 200 with an empty collection, since such a rule can carry no exclusion at all.
Removing an exclusion
curl -X DELETE https://app.scribee.tech/api/v1/bank_rule_exclusions/410 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
{
"data": {
"id": 410,
"workspace_id": 12,
"bank_rule_id": 88,
"company_id": 34,
"created_at": "2026-08-21T15:10:00+02:00",
"updated_at": "2026-08-21T15:10:00+02:00"
}
}
The response body is the exclusion as it stood when you asked for it to go. From the next classification on, the workspace rule is a candidate again for that company's operations.
The errors
| Status | error | code | When |
|---|---|---|---|
400 | bad_request | - | A page that is not an integer greater than or equal to 1, or a page beyond the last page of a non-empty collection |
403 | forbidden | - | Your OAuth client holds no grant on the workspace concerned, or the token does not carry the required scope |
404 | not_found | - | The rule or the exclusion is not reachable by your grants |
409 | - | idempotency_key_reuse | The same Idempotency-Key has already been used for a different body |
409 | - | idempotency_request_in_progress | An earlier call carrying that key is still in flight |
422 | unprocessable_entity | validation_failed | The target rule is a company rule, the company is already excluded, or the body carries no company_id |
422 | unprocessable_entity | invalid_argument | The company_id is not a company of the rule's workspace |
A resource out of reach answers 404, never 403. Reachability is settled before the question of rights: an exclusion in a workspace your grants do not cover and an exclusion that does not exist receive the same answer. That matters all the more on DELETE /api/v1/bank_rule_exclusions/{id}, whose path carries neither the rule nor the company.