Skip to content

What has been changed in this org’s settings

GET
/orgs/{org}/config/changes
curl --request GET \
--url 'https://api.sloose.com/orgs/org_9f3c/config/changes?connector=con_8f2a&page=modules&limit=50' \
--header 'Authorization: Bearer <token>'

Newest first, a page at a time — limit and cursor, answering nextCursor. One entry per changed VALUE rather than per request, because that is the shape of the question it answers — “who turned Contacts off, and when?” The entries of one request share a registryVersion, which is how to put them back together.

Scoped by page. A connection’s own pages — its modules, fields and write pause — are the connection ?connector= names, since an org with two CRMs has two histories and Contacts in both; handing over the pair interleaved would let a reader attribute one CRM’s change to the other. Every other page is the org’s and is returned whatever is named — among them Connections, whose rows each carry the connection they are about in connectorId. Without ?connector=, a connection’s own pages give nothing.

This is the org’s own record of its settings and its billing, and it is erased with the org. Most rows are its own people’s, and via says when one is not: on Plan and Usage & credits a change can come through Stripe, the schedule — or Sloose support, when a staff member gives the org a trial or credits, recorded here as staff with nobody named. Everything else we do to an org is staff_actions, which is not this, names the staff member, and outlives it.

org
required

The org id the session was issued for. A token for one org can never read another.

string
Example
org_9f3c

The org id the session was issued for. A token for one org can never read another.

connector

The connection whose history to include beside the org’s own, by id. Absent: the org’s own changes alone — except that asking only for a connection’s pages (modules, fields) without one is 400 CONNECTION_REQUIRED, listing the connections.

string
Example
con_8f2a

The connection whose history to include beside the org’s own, by id. Absent: the org’s own changes alone — except that asking only for a connection’s pages (modules, fields) without one is 400 CONNECTION_REQUIRED, listing the connections.

page
Any of:
string

Only this settings page’s changes. May be repeated — one section can show several pages’ history, which is what a connection’s modules do with modules and fields.

limit

How many to return, at most 200; 50 when absent. Anything but a whole number above zero — 0, negative, a fraction, not a number — is the default, never an error.

string
Example
50

How many to return, at most 200; 50 when absent. Anything but a whole number above zero — 0, negative, a fraction, not a number — is the default, never an error.

cursor

The nextCursor of the page before this one; absent for the first page. Opaque: it names a place in the list’s (createdAt, id) order, and a malformed one is 400 INVALID_CURSOR.

string

The nextCursor of the page before this one; absent for the first page. Opaque: it names a place in the list’s (createdAt, id) order, and a malformed one is 400 INVALID_CURSOR.

A page of changes, newest first.

Media typeapplication/json
object
changes
required
Array<object>
object
id
required
string
page
required

The settings page this change belongs to.

string
subject
required

module.enabled, settings.timezone, field.excludeFromAi, bundle, member.role, connection.name, connection.disconnected, …

string
target
required

What it was about, by name: the module or field, the person (People), the connection (Connections); null when it was the org’s own setting.

string | null
before

What it was — null when that was not knowable, which a whole-registry replacement and a bundle push are. Never a guess.

after
proposedBy
required

Whose proposal the new value was, when it was not the author’s own: ai when the person used a value the AI proposed (Ask AI on a module’s page). The author is still that person. Null for a value they gave themselves, and for every change recorded before this was.

string | null
Allowed values: ai
registryVersion
required

The version this change produced. The changes of one request share it.

number | null
userId
required

Who, as a person — null when an org API token made the change, since a token is the org’s and outlives whoever minted it, and null for the billing authors in via other than a person’s. An MCP bearer keeps its person.

string | null
userName
required

Their name as they gave it, resolved from users. Null when no person made the change — a token, or one of the billing authors in via. It does NOT go null for somebody who has left the org — that is the case the join exists for, and their users row outlives the membership.

string | null
userEmail
required

Their address, which is what an administrator recognises; null as userName is. Resolved through a LEFT join on purpose: somebody whose membership has been removed or revoked is no longer in GET /members, so a client that looked them up there would render the change being investigated as nobody — while this still names them.

string | null
via
required

How it arrived: a person’s session, an org API token or an MCP bearer — or, on Plan and Usage & credits, with nobody’s request behind it: stripe (the Customer Portal, Stripe’s dashboard, a subscription Stripe ended), schedule (a trial or a paid-up period running out, or a downgrade taking effect) and staff (Sloose support, from the backoffice). A plan bought through Checkout and a credit pack are the person who started the checkout, though Stripe’s webhook applies them.

string
Allowed values: session token oauth stripe schedule staff
tokenId
required

WHICH token, when via is token. Without it a token-authored change can only say “some token”, which is no answer when an org has several integrations.

string | null
tokenName
required

That token by the name whoever minted it chose. A REVOKED token still has one — revoking deletes nothing — so a change made before the revocation goes on naming it.

string | null
connectorId
required

The connection this change is about: the one whose registry it changed (modules, fields, its write pause), or, on Connections, the connection itself — added, reconnected, renamed, listed or disconnected. Null for a change about the org alone. Two connections can hold modules of the same name, so without this their changes are indistinguishable. Which rows a request is given is decided by PAGE, not by this column: see the route.

string | null
createdAt
required
string
nextCursor
required

Pass as cursor for the next page; null when this was the last.

string | null
Example
{
"changes": [
{
"proposedBy": "ai",
"via": "session"
}
]
}

Only a connection’s pages were asked for, and no connection was named (code: CONNECTION_REQUIRED, with connections), or cursor is malformed (code: INVALID_CURSOR).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

No bearer, or one that is expired, revoked or no longer resolves to a member.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

The bearer’s role is too low, or it was issued for a different org.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

?connector= names a connection this person may not use: another org’s, or another person’s (code: CONNECTION_NOT_FOUND).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

Report a problem with this page