Organization
Manage your Competitor Tracker & Co. organization: rename it, list members, change a role, invite or remove people, leave, transfer ownership or close it.
The operations on this page touch the organization's own lifecycle and membership — not its tracked data. They're scoped to the org bound to the access token's org_id claim, so the path is singular /v1/org with no id parameter (or /v1/org/members/{userId} when targeting one member). Our lead detective C. T. Lucky walks you through it. For parameter-level detail, see the API reference in the sidebar.
These operations interact closely with roles (see the Roles section on the Authentication page). What you can call here depends on your membership role in the current organization.
A user can belong to more than one organization, but a single access token only ever resolves one of them at a time. To enumerate every organization the signed-in user belongs to — the data behind an in-app org switcher — call GET /v1/users/me/orgs. It returns the org id, name, the user's role there and when they joined, alphabetical by org name.
List members
GET /v1/org/members
A cursor-paginated page of the current organization's active members, joined with the user's email and name. Admin-only.
curl "$CT_API/org/members?limit=50" \
-H "Authorization: Bearer $CT_TOKEN"Response:
{
"items": [
{
"userId": "01HF...",
"email": "alice@example.com",
"name": "Alice Example",
"role": "admin",
"joinedAt": "2026-05-04T10:23:00.000Z"
}
],
"nextCursor": null
}Query parameters:
limit— 1–200, default 50.cursor— opaque cursor returned innextCursorfrom a prior call. Stable under newest-first ordering by the member's join time.
Members are excluded from the response if their membership has been removed. The owner appears in the same list with role: "owner".
Change a member's role
PATCH /v1/org/members/{userId}
Promotes a member to admin or demotes an admin to member. Admin-only. The role field accepts only "admin" or "member" — owner is intentionally not assignable through this endpoint. Use Transfer ownership instead.
curl -X PATCH "$CT_API/org/members/01HF..." \
-H "Authorization: Bearer $CT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "role": "admin" }'Returns 200 OK:
{
"ok": true,
"userId": "01HF...",
"previousRole": "member",
"newRole": "admin"
}Same-role PATCH is an idempotent success. The request is a no-op when the target already holds the requested role, with no audit-log entry.
An admin may freely promote or demote any non-owner member, including self-demote. The owner provides admin-tier coverage through the role hierarchy (owner ⊃ admin ⊃ member), so an org never drops below "someone admin-capable" as long as it has an owner.
Errors:
404 OrgMemberNotFound— the targetuserIdis not an active member of the current organization.403 OwnerRoleImmutable— the target is currently the owner. UsePOST /v1/org/transfer-ownershipto change ownership.403 InsufficientRole— the caller is amember. The endpoint requiresadminor higher.
Successful changes write a member_role_changed audit-log entry with { actor_user_id, target_user_id, previous_role, new_role } metadata so the role timeline is reconstructible.
Rename the organization
PATCH /v1/org
Updates the display name of the current organization. Admin-only. Tokens don't roll over and members don't get signed out — the new name shows up on the next read of the org.
curl -X PATCH "$CT_API/org" \
-H "Authorization: Bearer $CT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Detective Co." }'Returns 200 OK:
{
"id": "01HF...",
"name": "Acme Detective Co.",
"ownAppDomain": null,
"createdAt": "2026-05-14T00:00:00.000Z",
"updatedAt": "2026-05-17T10:23:00.000Z"
}The name is trimmed of leading and trailing whitespace, then length-checked between 1 and 240 characters. Empty or whitespace-only names come back as 400 ValidationError. 403 InsufficientRole for member callers — only admin or owner can rename.
Every successful rename writes an org_renamed audit-log entry with { previousName, newName } so the rename timeline is reconstructible.
Leave
POST /v1/org/leave
Drops your membership in the current organization. The org keeps running for the remaining members. Your access token immediately stops resolving an active membership and subsequent requests return 403.
curl -X POST "$CT_API/org/leave" \
-H "Authorization: Bearer $CT_TOKEN"Returns 200 OK with { "ok": true }.
Owners can't leave directly. If you are the owner of the organization, this endpoint returns 409 OwnershipTransferRequired whether or not other owners exist. The constraint isn't about ownership ambiguity. It's about keeping the audit trail clean. Every change of ownership is recorded as an explicit ownership_transferred event with a known recipient, and that's only true if you call transfer-ownership first.
To leave as an owner: transfer ownership to another member first, then leave. You'll be an admin after the transfer, which can leave freely.
Transfer ownership
POST /v1/org/transfer-ownership
Hand the owner role to another active member of the same organization. The current owner is demoted to admin in the same operation. Both writes apply atomically. There is no intermediate state where the organization has zero owners.
curl -X POST "$CT_API/org/transfer-ownership" \
-H "Authorization: Bearer $CT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "to_user_id": "01HF..." }'Returns 200 OK:
{
"ok": true,
"previous_owner_id": "01HC...",
"new_owner_id": "01HF..."
}404 NotAnOrgMember if to_user_id doesn't match an active member of the current organization. The endpoint is owner-only. admin callers receive 403 InsufficientRole.
The transfer is instant. The new owner doesn't need to accept. Your existing access token (now scoped to admin) keeps working. The new owner's next token refresh — ≤15 min on natural rotation — picks up the elevated role.
Close the organization
DELETE /v1/org
Closes the organization. Returns 200 OK with { "ok": true }. Owner-only.
curl -X DELETE "$CT_API/org" \
-H "Authorization: Bearer $CT_TOKEN"What deletion means here:
- The organization disappears from your account view immediately.
- All of the org's competitors, labels, snapshots and changes become invisible to subsequent reads.
- Every membership in the org stops resolving. Subsequent requests bearing a token with that
org_idclaim return403because the auth context finds no active org.
Deletion is logical: data is retained server-side so we can support forensic review or support-mediated recovery, but the API surface treats the org as gone.
There is no undo endpoint. Recovery during the early-access phase requires contacting support. Once mature, an explicit restore flow may ship, but don't lean on it. Treat this call as terminal.
Picking between the three
- Leave if you want out and the org should continue running. Members and admins can leave directly. Owners transfer first.
- Transfer ownership if you're the owner and want to hand off the badge. The new owner takes effect immediately.
- Close if the organization isn't needed at all. Deletion is logical — data is retained server-side for forensics or support-mediated recovery, but the API treats the org as gone.
All lifecycle operations record an audit-log entry — member_left, ownership_transferred, org_deleted, member_role_changed — so the membership timeline is reconstructible after the fact.
Billing
How billing works in Competitor Tracker & Co.: coins fund each tracked competitor, how and when charges apply and the endpoints that surface your balance.
Onboarding
Set up Competitor Tracker & Co.: signup, completing your profile, inviting your team and claiming your application domain so the pack tracks the right site.