mine=true includes that filter. Teams grant no additional resource
access. An organization member with Write access can manage any shared team in that organization;
Read access is enough to inspect teams, rules, and users.
Discover an organization
Start without an organization header:{ "data": [{ "id": "org_...", "name": "Example" }], "next_cursor": null }.
Follow next_cursor with cursor until it is null. The default page size is 50; the maximum is 100.
Organizations are ordered by name, then ID.
Discovery requires a valid key or signed-in Clerk session, but no selected organization. A supplied
X-Organization-Id is ignored for this endpoint. Only synchronized memberships with a supported
organization role appear. Selected keys remain within their selected set; migrated keys remain
within their original organization. No memberships produces an empty page.
Discovery does not enforce organization MFA or grant resource access. For subsequent requests,
choose a returned organization ID and send X-Organization-Id. All normal role, key-access, and MFA
checks apply. Clerk sessions must first select that organization as active, and any supplied header
must match it. Membership changes appear after Clerk webhook synchronization.
Find members and create a team
GET /v1/members lists the selected organization’s current members,
including user_id, name, email, role and join date. Use user_id when adding a team member.
GET /v1/teams/{id}/members returns paginated {id, first_name, last_name, email} records.
Both lists are ordered by user ID. Names and email can be null. User and organization IDs are opaque strings; team IDs
are UUIDs. Pending invitations are not members.
201 and a Location header. Names are trimmed, limited to 100 characters, and
unique case-sensitively within the organization. Repeating a name returns 409 conflict.
The team initially has no members and no filter. You may provide a filter during creation.
GET /v1/teams remains a compact name-searchable selector with id, name, and
organization_number: null. Retrieve /v1/teams/{id} for the saved filter, created_at, and
updated_at; retrieve its /members endpoint for membership.
Define the predicate
A condition hasfield, op, and value. A group combines conditions or nested groups
using combinator: "and" or "or". There is no implicit precedence or group-level NOT.
The version-1 definition has schema_version: 1 and a root group. Maximums are 20 conditions
and three group levels, including the root. Empty groups and empty value lists are invalid.
This selects supplier A or B, and recipient C. Replace the placeholders with actual UUIDs:
is / is_not for one exact value and is_any_of / is_none_of for a list. All four accept
both a scalar and a nonempty array for compatibility. A positive list means any listed value;
a negative list excludes every listed value. Reference values must identify records in the
selected organization, including when used with negative operators.
Fields and operators
Exact text comparisons are case-sensitive and do not trim or normalize stored rule values.
contains and not_contains accept a single nonempty string, are case-insensitive, and treat
% and _ literally. Exact text operators also accept a nonempty string array.
invoice.amount uses the invoice total including VAT. It performs no currency conversion.
Use decimal strings when exact precision matters. Date values must be real calendar dates.
within accepts last_30_days, last_90_days, last_365_days, expiring_30_days,
expiring_60_days, or expiring_90_days. These ranges include both endpoints and use the current
UTC date on each request.
invoice.reference checks contract, buyer, seller, project, credit-note invoice and payment
references, plus exact elements of order_references. Substring operators do not search the
order-reference array. invoice.delivery_address checks delivery name, street, postal code, city,
state, and country. A positive condition matches any supported component; a negative condition
requires every supported component to avoid the value.
Which records are evaluated?
Conditions over related records are evaluated independently. For example, an agreement linked
to a USD 2,000 invoice and a NOK 100 invoice matches
invoice.amount > 1000 AND invoice.currency is NOK.
One invoice satisfies each condition; no single invoice needs to satisfy both. Grouping those
conditions with AND does not introduce a same-invoice requirement. The same principle applies to
conditions over multiple matched agreements or linked suppliers. Version 1 has no same-related-record group.
For related collections, a positive condition needs a matching related record; a negative condition
means no related record matches its corresponding positive condition. Empty relationships therefore
satisfy negative conditions. On nullable scalar fields, negative exact/substring conditions include
null, while positive, numeric, and date comparisons require a value. Normal resource visibility and
deletion rules still apply.
An alert uses its own agreement: another agreement matched to the same invoice cannot satisfy its
agreement rules. Claims match through their agreement even without attached alerts. Team predicates
select complete claims; they do not trim claim members or refund totals.
Save a supplier / recipient / tag rule
Resolve IDs through/v1/suppliers, /v1/recipients, and /v1/agreements/tags. Follow their
pagination when selecting records. With your chosen UUIDs in the variables below:
filter to preserve it, or send {"filter":null} to clear it. Clearing matches
no records; it does not mean match everything. Name and filter edits commit together.
Invalid writes return 400 validation_error with up to 20 details identifying fields such as
filter.root.children.0. Foreign references are reported as unavailable without disclosing foreign
records. Read responses preserve malformed legacy JSON so it can be inspected. Replace or clear it
to repair it; an unrelated name edit leaves it unchanged. Selecting a team with unsupported stored
rules returns 409 conflict until those rules are corrected.
Add a member and observe the scope
Formine=true, add the authenticated key owner or session user. Their ID is available in /v1/me:
user_id from /v1/members.
New membership returns 201; repeated addition returns the existing user with 200.
Missing/foreign users or teams and personal subscriptions return 404.
mine=true unions the user’s shared team predicates with OR. Explicit team_ids unions the
selected teams, regardless of membership. Ordinary query filters narrow that union with AND.
Selecting the same record through multiple teams does not duplicate records or totals.
mine=true and team_ids together return 400; explicit selection accepts up to 50 teams.
No memberships or no saved predicates produces empty lists/groups and zero metrics.
Changes to rules and memberships apply on subsequent requests, including requests using an existing
cursor. Pagination remains live: keep the same user, organization, query, and ordering. There is no
snapshot, automatic restart, or scope version. Cursors cannot be transferred between queries.
Remove membership or delete the team
204, including when a current organization user is already absent.
Removing the last member is allowed; the team and its filter remain usable through team_ids.
Team deletion returns 204 and permanently removes the team, saved filter, and membership links.
It does not delete organization users or business records. There is no restore. Missing or already
deleted teams return 404. The deleted team stops contributing to mine; explicit team_ids
containing it returns 404, including on later pages. Personal subscriptions are outside this API.