Which API endpoints does RevenueDot Enterprise add?

These endpoints exist only on a server that runs RevenueDot Enterprise: one started with REVENUEDOT_LICENSE_KEY, or with REVENUEDOT_EE_DEV=true for development. Each group also needs its feature in the licence; without it the route answers 403. The open-source build has none of them. Organization endpoints take a dashboard session (the rd_session cookie); secret API keys belong to one project and cannot call them. Writes from a browser must come from the dashboard's own site. The SCIM 2.0 service under /scim/v2 takes a SCIM token instead. The /sso endpoints take no credentials: browsers and identity providers call them during sign-in. Errors use the REST API v2 format, except under /scim/v2, which answers RFC 7644 errors. The examples also read ORG_ID and SCIM_TOKEN from your shell.

Base URL: your server, for example http://localhost:8787 or https://revenuedot.example.com. The examples read REVENUEDOT_URL, PUBLIC_KEY, SECRET_KEY and PROJECT_ID from your shell.

Operations on this page (65)#

Enterprise#

Whether this server runs RevenueDot Enterprise, with which licence and features. See Enterprise.

Licence state and features#

GET /v2/enterprise · Auth: dashboard session · RevenueDot extension

Any signed-in user. The route exists only when the server was started with REVENUEDOT_LICENSE_KEY or REVENUEDOT_EE_DEV=true; the open-source build answers 404. With an invalid key it still answers, with mode: invalid and no features, and no other enterprise route exists.

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/enterprise"

Responses

Example 200 response:

JSON
{
  "object": "enterprise",
  "mode": "development",
  "features": [
    "organizations",
    "custom_roles",
    "sso",
    "scim",
    "data_location",
    "audit_retention",
    "compliance_exports"
  ],
  "licensee": null,
  "expires_at": null,
  "message": "Development mode: for development and testing only, not for production (ee/LICENSE)."
}

Organizations#

Organizations own projects and hold members with owner, admin and member roles, seats, data location, audit retention and the organization audit log. Dashboard session only. See Enterprise.

Organizations you belong to#

GET /v2/organizations · Auth: dashboard session · RevenueDot extension

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations"

Responses

  • 200: Every organization where you are an active member, oldest first. Returns a list of Organization.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.

Example 200 response:

JSON
{
  "object": "list",
  "items": [
    {
      "object": "organization",
      "id": "org_k2m9q4x7z1a8",
      "name": "Acme Inc.",
      "your_role": "owner",
      "region": "us",
      "region_name": "United States",
      "selectable_regions": [
        "us",
        "eu"
      ],
      "region_enforced": false,
      "audit_retention_days": 365,
      "sso_enforced": true,
      "seats": {
        "purchased": 50,
        "used": 23
      },
      "billing_email": "finance@acme.com",
      "member_count": 23,
      "project_count": 3,
      "features": [
        "organizations",
        "custom_roles",
        "sso",
        "scim",
        "data_location",
        "audit_retention",
        "compliance_exports"
      ],
      "created_at": 1790800914012,
      "updated_at": 1790887314012
    }
  ],
  "next_page": null,
  "url": "/v2/organizations"
}

Create an organization#

POST /v2/organizations · Auth: dashboard session · RevenueDot extension

You become its owner. region defaults to this deployment's region. A licence with an organization limit answers 403 once the server has that many organizations.

Request body (application/json)

Field Type Required Description
name string yes
region us, eu no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations" \
  -H "Content-Type: application/json" -d '{"name":"Acme Inc."}'

Responses

  • 201: The new organization. Returns Organization.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.

Example 201 response:

JSON
{
  "object": "organization",
  "id": "org_k2m9q4x7z1a8",
  "name": "Acme Inc.",
  "your_role": "owner",
  "region": "us",
  "region_name": "United States",
  "selectable_regions": [
    "us",
    "eu"
  ],
  "region_enforced": false,
  "audit_retention_days": 365,
  "sso_enforced": true,
  "seats": {
    "purchased": 50,
    "used": 23
  },
  "billing_email": "finance@acme.com",
  "member_count": 23,
  "project_count": 3,
  "features": [
    "organizations",
    "custom_roles",
    "sso",
    "scim",
    "data_location",
    "audit_retention",
    "compliance_exports"
  ],
  "created_at": 1790800914012,
  "updated_at": 1790887314012
}

Get an organization#

GET /v2/organizations/{org_id} · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID"

Responses

  • 200: The organization. Returns Organization.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "organization",
  "id": "org_k2m9q4x7z1a8",
  "name": "Acme Inc.",
  "your_role": "owner",
  "region": "us",
  "region_name": "United States",
  "selectable_regions": [
    "us",
    "eu"
  ],
  "region_enforced": false,
  "audit_retention_days": 365,
  "sso_enforced": true,
  "seats": {
    "purchased": 50,
    "used": 23
  },
  "billing_email": "finance@acme.com",
  "member_count": 23,
  "project_count": 3,
  "features": [
    "organizations",
    "custom_roles",
    "sso",
    "scim",
    "data_location",
    "audit_retention",
    "compliance_exports"
  ],
  "created_at": 1790800914012,
  "updated_at": 1790887314012
}

Update an organization#

POST /v2/organizations/{org_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Changing audit_retention_days, seats or billing_email needs an owner. sso_enforced: true needs an enabled SSO connection and a verified domain (422 otherwise). region must be one of selectable_regions. Each field needs its feature in the licence (403 otherwise). Changes are recorded in the organization audit log as organization_updated.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
name string no
region us, eu no Default data location for projects.
audit_retention_days integer or null no 30 to 3650. Null keeps audit logs forever.
sso_enforced boolean no Require single sign-on for the organization's verified domains.
seats integer or null no Seats bought, 1 to 100000.
billing_email string or null no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID" \
  -H "Content-Type: application/json" -d '{"audit_retention_days":365,"sso_enforced":true}'

Responses

  • 200: The updated organization. Returns Organization.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

Example 200 response:

JSON
{
  "object": "organization",
  "id": "org_k2m9q4x7z1a8",
  "name": "Acme Inc.",
  "your_role": "owner",
  "region": "us",
  "region_name": "United States",
  "selectable_regions": [
    "us",
    "eu"
  ],
  "region_enforced": false,
  "audit_retention_days": 365,
  "sso_enforced": true,
  "seats": {
    "purchased": 50,
    "used": 23
  },
  "billing_email": "finance@acme.com",
  "member_count": 23,
  "project_count": 3,
  "features": [
    "organizations",
    "custom_roles",
    "sso",
    "scim",
    "data_location",
    "audit_retention",
    "compliance_exports"
  ],
  "created_at": 1790800914012,
  "updated_at": 1790887314012
}

Delete an organization#

DELETE /v2/organizations/{org_id} · Auth: dashboard session · RevenueDot extension

Organization owners only. Move every project out first (422 otherwise). Its SSO connections, domains, SCIM tokens, custom roles, mappings and organization audit log are deleted.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID"

Responses

  • 200: Deleted.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

Example 200 response:

JSON
{
  "object": "organization",
  "id": "org_k2m9q4x7z1a8",
  "deleted_at": 1790887314012
}

Organization with SSO and SCIM counts#

GET /v2/organizations/{org_id}/overview · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/overview"

Responses

  • 200: The organization plus counts.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

List members#

GET /v2/organizations/{org_id}/members · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Includes deactivated members (active: false).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/members"

Responses

  • 200: Members, oldest first. Returns a list of OrganizationMember.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Add an existing account#

POST /v2/organizations/{org_id}/members · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Only owners add owners. The address must already have a RevenueDot account (404 otherwise); new people join through single sign-on, SCIM or a project invite. Owners and admins become Admins of every organization project; group role mappings apply at once.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
email string yes
role owner, admin, member no Default member.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/members" \
  -H "Content-Type: application/json" -d '{"email":"sam@acme.com","role":"admin"}'

Responses

  • 201: The member. Returns OrganizationMember.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 409: It already exists, or it conflicts with another object. Returns V2Error.

Change a member's organization role#

POST /v2/organizations/{org_id}/members/{user_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Only owners make or unmake owners, and the last owner cannot be demoted (400). Promoting to admin or owner adds Admin access to every organization project; demoting removes the access that came from the organization role.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
user_id string yes User id.

Request body (application/json)

Field Type Required Description
role owner, admin, member yes

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/members/$USER_ID" \
  -H "Content-Type: application/json" -d '{"role":"member"}'

Responses

  • 200: The member. Returns OrganizationMember.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Remove a member, or leave#

DELETE /v2/organizations/{org_id}/members/{user_id} · Auth: dashboard session · RevenueDot extension

Admins remove members; only owners remove owners; anyone may remove themselves. The last owner cannot leave (422). The person loses every membership in the organization's projects, including ones added by hand.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
user_id string yes User id. Your own to leave.

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/members/$USER_ID"

Responses

  • 200: Removed.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

List the organization's projects#

GET /v2/organizations/{org_id}/projects · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects"

Responses

  • 200: Projects with their region and member count. Returns a list of OrganizationProject.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Move a project into the organization#

POST /v2/organizations/{org_id}/projects · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). You must also be an Admin of the project (403 otherwise). A project belongs to one organization at a time (409). The project is recorded in this deployment's region; no data moves. Everyone on the project becomes an organization member, and organization owners and admins become its Admins.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
project_id string yes

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects" \
  -H "Content-Type: application/json" -d '{"project_id":"proj18pzzkao"}'

Responses

  • 201: The project.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 409: It already exists, or it conflicts with another object. Returns V2Error.

Move a project out#

DELETE /v2/organizations/{org_id}/projects/{project_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Memberships stay. Members with a custom role become Viewers, because the organization's roles no longer apply there.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
project_id string yes Project id (proj...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects/$PROJECT_ID"

Responses

  • 200: Moved out.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Set a project's data location#

POST /v2/organizations/{org_id}/projects/{project_id}/region · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Needs the data_location feature. On a deployment that enforces regions, a project stays in the region where its data is (422 with the other region's dashboard address, or "not available yet"); moving stored data is a support job. Elsewhere the region is recorded.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
project_id string yes Project id (proj...).

Request body (application/json)

Field Type Required Description
region us, eu yes

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects/$PROJECT_ID/region" \
  -H "Content-Type: application/json" -d '{"region":"eu"}'

Responses

  • 200: The project's region.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

The organization audit log#

GET /v2/organizations/{org_id}/audit_logs · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Newest first. Project audit logs stay at GET /v2/projects/{project_id}/audit_logs.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Query parameters

Name Type Required Description
start_time integer no Only entries at or after this time (epoch milliseconds).
end_time integer no Only entries before this time (epoch milliseconds).
limit integer no Page size. Values outside 1-100 are clamped, not rejected.
starting_after string no Id of the last item of the previous page. Use next_page instead of building it.

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/audit_logs"

Responses

  • 200: A page of entries. Returns a list of OrganizationAuditLog.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Custom roles#

Roles built from API v2 scopes, their assignment to project members, and group role mappings for SSO and SCIM groups. See Enterprise.

Scopes a custom role can hold#

GET /v2/organizations/{org_id}/scopes · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/scopes"

Responses

  • 200: 33 scopes in 5 groups.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "scope_catalogue",
  "groups": [
    {
      "group": "Customers",
      "scopes": [
        {
          "scope": "customer_information:customers:read",
          "label": "View customers"
        }
      ]
    }
  ]
}

List custom roles#

GET /v2/organizations/{org_id}/roles · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/roles"

Responses

  • 200: Roles, oldest first. Returns a list of CustomRole.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "list",
  "items": [
    {
      "object": "custom_role",
      "id": "role_8f2kq0x1m3zv",
      "name": "Support agent",
      "description": "Refunds and customer lookups, no catalog changes.",
      "scopes": [
        "customer_information:customers:read",
        "customer_information:purchases:read_write",
        "customer_information:subscriptions:read_write"
      ],
      "project_id": null,
      "member_count": 4,
      "created_at": 1790800914012,
      "updated_at": 1790800914012
    }
  ],
  "next_page": null,
  "url": "/v2/organizations/org_k2m9q4x7z1a8/roles"
}

Create a custom role#

POST /v2/organizations/{org_id}/roles · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Unknown scopes and project_configuration:api_keys:read_write are refused (400). A name already used in the organization answers 409.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
name string yes
description string or null no
scopes array of string yes
project_id string or null no Limit the role to one project of the organization.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/roles" \
  -H "Content-Type: application/json" -d '{"name":"Support agent","description":"Refunds and customer lookups, no catalog changes.","scopes":["customer_information:customers:read","customer_information:purchases:read_write","customer_information:subscriptions:read_write"]}'

Responses

  • 201: The role. Returns CustomRole.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 409: It already exists, or it conflicts with another object. Returns V2Error.

Example 201 response:

JSON
{
  "object": "custom_role",
  "id": "role_8f2kq0x1m3zv",
  "name": "Support agent",
  "description": "Refunds and customer lookups, no catalog changes.",
  "scopes": [
    "customer_information:customers:read",
    "customer_information:purchases:read_write",
    "customer_information:subscriptions:read_write"
  ],
  "project_id": null,
  "member_count": 4,
  "created_at": 1790800914012,
  "updated_at": 1790800914012
}

Get a custom role#

GET /v2/organizations/{org_id}/roles/{role_id} · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
role_id string yes Role id (role_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/roles/$ROLE_ID"

Responses

  • 200: The role. Returns CustomRole.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "custom_role",
  "id": "role_8f2kq0x1m3zv",
  "name": "Support agent",
  "description": "Refunds and customer lookups, no catalog changes.",
  "scopes": [
    "customer_information:customers:read",
    "customer_information:purchases:read_write",
    "customer_information:subscriptions:read_write"
  ],
  "project_id": null,
  "member_count": 4,
  "created_at": 1790800914012,
  "updated_at": 1790800914012
}

Update a custom role#

POST /v2/organizations/{org_id}/roles/{role_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). New scopes apply to everyone with the role on their next request. A role in use cannot change its project (400).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
role_id string yes Role id (role_...).

Request body (application/json)

Field Type Required Description
name string no
description string or null no
scopes array of string no
project_id string or null no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/roles/$ROLE_ID" \
  -H "Content-Type: application/json" -d '{"scopes":["customer_information:customers:read","customer_information:purchases:read"]}'

Responses

  • 200: The role. Returns CustomRole.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 409: It already exists, or it conflicts with another object. Returns V2Error.

Example 200 response:

JSON
{
  "object": "custom_role",
  "id": "role_8f2kq0x1m3zv",
  "name": "Support agent",
  "description": "Refunds and customer lookups, no catalog changes.",
  "scopes": [
    "customer_information:customers:read",
    "customer_information:purchases:read_write",
    "customer_information:subscriptions:read_write"
  ],
  "project_id": null,
  "member_count": 4,
  "created_at": 1790800914012,
  "updated_at": 1790800914012
}

Delete a custom role#

DELETE /v2/organizations/{org_id}/roles/{role_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Everyone with the role becomes a Viewer, and group role mappings that gave it are deleted.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
role_id string yes Role id (role_...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/roles/$ROLE_ID"

Responses

  • 200: Deleted.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

A project's members with role names#

GET /v2/organizations/{org_id}/projects/{project_id}/members · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
project_id string yes Project id (proj...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects/$PROJECT_ID/members"

Responses

  • 200: The project's members. Returns a list of OrganizationProjectMember.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Give a project member a built-in or custom role#

POST /v2/organizations/{org_id}/projects/{project_id}/members/{user_id} · Auth: dashboard session · RevenueDot extension

Organization admins, or Admins of the project. The person must already be a member of the project (404). The role must be admin, developer, viewer, or a custom role of the organization for every project or for this one (400). The last Admin and the project owner stay Admins. A role set here is never changed by group role mappings.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
project_id string yes Project id (proj...).
user_id string yes User id.

Request body (application/json)

Field Type Required Description
role string yes admin, developer, viewer or a custom role id.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/projects/$PROJECT_ID/members/$USER_ID" \
  -H "Content-Type: application/json" -d '{"role":"role_8f2kq0x1m3zv"}'

Responses

  • 200: The membership.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

Example 200 response:

JSON
{
  "object": "project_member",
  "user_id": "usr_8f2kq0x1m3zv7a2b",
  "project_id": "proj18pzzkao",
  "role": "role_8f2kq0x1m3zv",
  "role_name": "Support agent"
}

List group role mappings#

GET /v2/organizations/{org_id}/role_mappings · Auth: dashboard session · RevenueDot extension

Any active member of the organization. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/role_mappings"

Responses

  • 200: Mappings by group. Returns a list of RoleMapping.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "list",
  "items": [
    {
      "object": "role_mapping",
      "id": "map_4f8k2m9q1x7z",
      "group": "RevenueDot Support",
      "project_id": "proj18pzzkao",
      "project_name": "Scanner",
      "role": "role_8f2kq0x1m3zv",
      "role_name": "Support agent",
      "created_at": 1790800914012
    }
  ],
  "next_page": null,
  "url": "/v2/organizations/org_k2m9q4x7z1a8/role_mappings"
}

Map a group to a role in a project#

POST /v2/organizations/{org_id}/role_mappings · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). One mapping per group and project: saving the same pair again replaces its role (200). Every member's access is re-applied at once; memberships_changed counts the changes.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
group string yes
project_id string yes
role string yes admin, developer, viewer or a custom role id.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/role_mappings" \
  -H "Content-Type: application/json" -d '{"group":"RevenueDot Support","project_id":"proj18pzzkao","role":"role_8f2kq0x1m3zv"}'

Responses

  • 200: Replaced.
  • 201: Created.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Delete a group role mapping#

DELETE /v2/organizations/{org_id}/role_mappings/{mapping_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Memberships that the mapping created are removed or lowered at once.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
mapping_id string yes Mapping id (map_...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/role_mappings/$MAPPING_ID"

Responses

  • 200: Deleted.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Single sign-on#

SAML 2.0 and OpenID Connect connections, verified email domains, and the public sign-in endpoints the browser and the identity provider call. See Single sign-on.

List SSO connections#

GET /v2/organizations/{org_id}/sso/connections · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/connections"

Responses

  • 200: Connections, oldest first. Returns a list of SsoConnection.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Create a SAML or OpenID Connect connection#

POST /v2/organizations/{org_id}/sso/connections · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Send saml for a SAML connection or oidc for OpenID Connect. A connection starts turned off unless enabled is true. The answer's sp holds the values to enter in the identity provider.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
kind saml, oidc yes
name string yes
enabled boolean no
jit boolean no Default true.
saml object no
saml.metadata_xml string no The identity provider's metadata XML. Fills the entity ID, the HTTP-Redirect sign-in URL and the signing certificates.
saml.idp_entity_id string no
saml.idp_sso_url string no
saml.idp_certificates array of string no
saml.allow_idp_initiated boolean no
saml.email_attribute string or null no
saml.first_name_attribute string or null no
saml.last_name_attribute string or null no
saml.groups_attribute string or null no
oidc object no
oidc.issuer string no
oidc.client_id string no
oidc.client_secret string or null no Stored encrypted, never returned. Null removes it.
oidc.scopes array of string no
oidc.groups_claim string or null no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/connections" \
  -H "Content-Type: application/json" -d '{"kind":"oidc","name":"Google Workspace","oidc":{"issuer":"https://accounts.google.com","client_id":"1234567890-abc.apps.googleusercontent.com","client_secret":"GOCSPX-..."}}'

Responses

  • 201: The connection. Returns SsoConnection.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 201 response:

JSON
{
  "object": "sso_connection",
  "id": "ssoc_p3k8x2m4q9z1",
  "org_id": "org_k2m9q4x7z1a8",
  "kind": "saml",
  "name": "Okta",
  "enabled": true,
  "jit": true,
  "created_at": 1790800914012,
  "updated_at": 1790800914012,
  "saml": {
    "idp_entity_id": "http://www.okta.com/exk1a2b3c4d5",
    "idp_sso_url": "https://acme.okta.com/app/acme_revenuedot_1/exk1a2b3c4d5/sso/saml",
    "idp_certificates": [
      "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----"
    ],
    "allow_idp_initiated": false,
    "email_attribute": null,
    "first_name_attribute": null,
    "last_name_attribute": null,
    "groups_attribute": "groups"
  },
  "sp": {
    "entity_id": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "acs_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/acs",
    "metadata_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "start_url": "https://app.revenuedot.app/sso/connections/ssoc_p3k8x2m4q9z1/start"
  }
}

Get an SSO connection#

GET /v2/organizations/{org_id}/sso/connections/{connection_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
connection_id string yes Connection id (ssoc_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/connections/$CONNECTION_ID"

Responses

  • 200: The connection. Returns SsoConnection.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "sso_connection",
  "id": "ssoc_p3k8x2m4q9z1",
  "org_id": "org_k2m9q4x7z1a8",
  "kind": "saml",
  "name": "Okta",
  "enabled": true,
  "jit": true,
  "created_at": 1790800914012,
  "updated_at": 1790800914012,
  "saml": {
    "idp_entity_id": "http://www.okta.com/exk1a2b3c4d5",
    "idp_sso_url": "https://acme.okta.com/app/acme_revenuedot_1/exk1a2b3c4d5/sso/saml",
    "idp_certificates": [
      "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----"
    ],
    "allow_idp_initiated": false,
    "email_attribute": null,
    "first_name_attribute": null,
    "last_name_attribute": null,
    "groups_attribute": "groups"
  },
  "sp": {
    "entity_id": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "acs_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/acs",
    "metadata_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "start_url": "https://app.revenuedot.app/sso/connections/ssoc_p3k8x2m4q9z1/start"
  }
}

Update an SSO connection#

POST /v2/organizations/{org_id}/sso/connections/{connection_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Fields you leave out keep their value. An organization that requires SSO cannot turn off its last enabled connection (422).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
connection_id string yes Connection id (ssoc_...).

Request body (application/json)

Field Type Required Description
name string no
enabled boolean no
jit boolean no
saml object no
saml.metadata_xml string no The identity provider's metadata XML. Fills the entity ID, the HTTP-Redirect sign-in URL and the signing certificates.
saml.idp_entity_id string no
saml.idp_sso_url string no
saml.idp_certificates array of string no
saml.allow_idp_initiated boolean no
saml.email_attribute string or null no
saml.first_name_attribute string or null no
saml.last_name_attribute string or null no
saml.groups_attribute string or null no
oidc object no
oidc.issuer string no
oidc.client_id string no
oidc.client_secret string or null no Stored encrypted, never returned. Null removes it.
oidc.scopes array of string no
oidc.groups_claim string or null no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/connections/$CONNECTION_ID" \
  -H "Content-Type: application/json" -d '{"enabled":true}'

Responses

  • 200: The connection. Returns SsoConnection.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

Example 200 response:

JSON
{
  "object": "sso_connection",
  "id": "ssoc_p3k8x2m4q9z1",
  "org_id": "org_k2m9q4x7z1a8",
  "kind": "saml",
  "name": "Okta",
  "enabled": true,
  "jit": true,
  "created_at": 1790800914012,
  "updated_at": 1790800914012,
  "saml": {
    "idp_entity_id": "http://www.okta.com/exk1a2b3c4d5",
    "idp_sso_url": "https://acme.okta.com/app/acme_revenuedot_1/exk1a2b3c4d5/sso/saml",
    "idp_certificates": [
      "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----"
    ],
    "allow_idp_initiated": false,
    "email_attribute": null,
    "first_name_attribute": null,
    "last_name_attribute": null,
    "groups_attribute": "groups"
  },
  "sp": {
    "entity_id": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "acs_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/acs",
    "metadata_url": "https://app.revenuedot.app/sso/saml/ssoc_p3k8x2m4q9z1/metadata",
    "start_url": "https://app.revenuedot.app/sso/connections/ssoc_p3k8x2m4q9z1/start"
  }
}

Delete an SSO connection#

DELETE /v2/organizations/{org_id}/sso/connections/{connection_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). An organization that requires SSO cannot delete its last enabled connection (422).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
connection_id string yes Connection id (ssoc_...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/connections/$CONNECTION_ID"

Responses

  • 200: Deleted.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 422: The request is valid but cannot be done in this state or for this store. Returns V2Error.

List email domains#

GET /v2/organizations/{org_id}/sso/domains · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/domains"

Responses

  • 200: Domains, oldest first. Returns a list of SsoDomain.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Add an email domain#

POST /v2/organizations/{org_id}/sso/domains · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Answers the TXT record to publish. Public mail providers such as gmail.com are refused (400). A domain another organization verified answers 409; an unverified claim by another organization does not block you. Adding a domain you already have answers 200.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
domain string yes

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/domains" \
  -H "Content-Type: application/json" -d '{"domain":"acme.com"}'

Responses

  • 200: Already added. Returns SsoDomain.
  • 201: The domain, not verified yet. Returns SsoDomain.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 409: It already exists, or it conflicts with another object. Returns V2Error.

Check the domain's TXT record#

POST /v2/organizations/{org_id}/sso/domains/{domain}/actions/verify · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Looks up _revenuedot-sso.<domain> with DNS over HTTPS (Cloudflare's resolver). At most 10 checks a minute per organization (429). A verified domain stays verified if a later check fails.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
domain string yes The domain, such as acme.com.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/domains/acme.com/actions/verify"

Responses

  • 200: The domain, with the TXT values found.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.
  • 429: Too many requests. Retry later. Returns V2Error.

Example 200 response:

JSON
{
  "object": "sso_domain",
  "domain": "acme.com",
  "verified": true,
  "verified_at": 1790801000000,
  "txt_record": {
    "type": "TXT",
    "name": "_revenuedot-sso.acme.com",
    "value": "revenuedot-sso-verification=3f9a1c0e7b2d4a6f8e1c3b5a7d9f0e2c"
  },
  "last_checked_at": 1790801000000,
  "last_error": null,
  "created_at": 1790800914012,
  "found": {
    "txt": [
      "revenuedot-sso-verification=3f9a1c0e7b2d4a6f8e1c3b5a7d9f0e2c"
    ]
  }
}

Remove an email domain#

DELETE /v2/organizations/{org_id}/sso/domains/{domain} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
domain string yes The domain, such as acme.com.

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/sso/domains/acme.com"

Responses

  • 200: Removed.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Does this address sign in with SSO?#

POST /sso/lookup · Auth: none · RevenueDot extension

No session. True when the address is on a domain an organization verified and that organization has an enabled connection.

Request body (application/json)

Field Type Required Description
email string yes
next string no A path on this site to open after sign-in.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/sso/lookup" \
  -H "Content-Type: application/json" -d '{"email":"sam@acme.com"}'

Responses

  • 200: The answer.

Example 200 response:

JSON
{
  "sso": true,
  "url": "/sso/start?email=sam%40acme.com"
}

Start a sign-in for an email address#

GET /sso/start · Auth: none · RevenueDot extension

Opens in the browser. Finds the organization that verified the address's domain and sends the browser to its first enabled connection (oldest first). At most 30 starts a minute per IP address. Failures redirect to /login?sso_error=<code>, one of failed, connection_off, rate_limited, not_set_up, domain_not_verified, access_removed, not_a_member, other_browser or idp_error; the sign-in page shows the message for the code, and the exact reason goes to the organization audit log as sso_sign_in_failed.

Query parameters

Name Type Required Description
email string yes The work email address.
next string no A path on this site to open after sign-in. Anything else becomes /.

Example request

Shell
curl -s "$REVENUEDOT_URL/sso/start"

Responses

  • 303: To the identity provider, or to /login?sso_error=....

Start a sign-in with one connection#

GET /sso/connections/{id}/start · Auth: none · RevenueDot extension

The start_url of a connection. Failures redirect to /login?sso_error=<code>, one of failed, connection_off, rate_limited, not_set_up, domain_not_verified, access_removed, not_a_member, other_browser or idp_error; the sign-in page shows the message for the code, and the exact reason goes to the organization audit log as sso_sign_in_failed.

Path parameters

Name Type Required Description
id string yes Connection id (ssoc_...).

Query parameters

Name Type Required Description
next string no A path on this site to open after sign-in.

Example request

Shell
curl -s "$REVENUEDOT_URL/sso/connections/$ID/start"

Responses

  • 303: To the identity provider, or to /login?sso_error=....

SAML service provider metadata#

GET /sso/saml/{id}/metadata · Auth: none · RevenueDot extension

This URL is also the connection's entity ID.

Path parameters

Name Type Required Description
id string yes Connection id (ssoc_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/sso/saml/$ID/metadata"

Responses

  • 200: The metadata.
  • 404: No SAML connection with this id.

SAML assertion consumer service#

POST /sso/saml/{id}/acs · Auth: none · RevenueDot extension

The identity provider posts the SAML response here (HTTP-POST binding). RevenueDot checks the assertion's signature, audience, recipient, destination, issuer, validity times (60 seconds of leeway) and that the answer belongs to a sign-in this browser started; each assertion is accepted once. Responses without an InResponseTo are IdP-initiated and are refused unless the connection allows them. On success it sets the session cookie. Failures redirect to /login?sso_error=<code>, one of failed, connection_off, rate_limited, not_set_up, domain_not_verified, access_removed, not_a_member, other_browser or idp_error; the sign-in page shows the message for the code, and the exact reason goes to the organization audit log as sso_sign_in_failed.

Path parameters

Name Type Required Description
id string yes Connection id (ssoc_...).

Request body (application/x-www-form-urlencoded)

Field Type Required Description
SAMLResponse string yes Base64 SAML response.
RelayState string no For IdP-initiated sign-in: a path to open after sign-in.

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/sso/saml/$ID/acs"

Responses

  • 303: To the page the person started from, or to /login?sso_error=....

OpenID Connect redirect URI#

GET /sso/oidc/{id}/callback · Auth: none · RevenueDot extension

The identity provider sends the browser back here. RevenueDot checks the state against the browser that started the sign-in, exchanges the code with PKCE, and verifies the ID token (issuer, audience, expiry, nonce, azp). The token must have an email claim, and email_verified must not be false. Failures redirect to /login?sso_error=<code>, one of failed, connection_off, rate_limited, not_set_up, domain_not_verified, access_removed, not_a_member, other_browser or idp_error; the sign-in page shows the message for the code, and the exact reason goes to the organization audit log as sso_sign_in_failed.

Path parameters

Name Type Required Description
id string yes Connection id (ssoc_...).

Query parameters

Name Type Required Description
state string no
code string no
error string no

Example request

Shell
curl -s "$REVENUEDOT_URL/sso/oidc/$ID/callback"

Responses

  • 303: To the page the person started from, or to /login?sso_error=....

SCIM 2.0#

SCIM tokens and groups in the dashboard API, and the SCIM 2.0 service (RFC 7643, RFC 7644) that Okta, Microsoft Entra ID and other identity providers call with a SCIM token. Bodies and errors use application/scim+json. See SCIM.

List SCIM tokens#

GET /v2/organizations/{org_id}/scim/tokens · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Never returns the secret.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/scim/tokens"

Responses

  • 200: Tokens, revoked ones included. Returns a list of ScimToken.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Create a SCIM token#

POST /v2/organizations/{org_id}/scim/tokens · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). The answer holds the token (rdscim_ and 64 hex characters) once; RevenueDot stores only its SHA-256. base_url is the SCIM base URL for the identity provider.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Request body (application/json)

Field Type Required Description
name string yes

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/v2/organizations/$ORG_ID/scim/tokens" \
  -H "Content-Type: application/json" -d '{"name":"Okta"}'

Responses

  • 201: The token, shown once.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 201 response:

JSON
{
  "object": "scim_token",
  "id": "sct_m3k9q2x8z1a4",
  "name": "Okta",
  "prefix": "rdscim_4f8a1c",
  "created_by": "usr_8f2kq0x1m3zv7a2b",
  "created_at": 1790800914012,
  "last_used_at": null,
  "revoked_at": null,
  "token": "rdscim_4f8a1c…",
  "base_url": "https://app.revenuedot.app/scim/v2"
}

Revoke a SCIM token#

DELETE /v2/organizations/{org_id}/scim/tokens/{token_id} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). Requests with the token answer 401 at once. Revoking twice answers the token again.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
token_id string yes Token id (sct_...).

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/v2/organizations/$ORG_ID/scim/tokens/$TOKEN_ID"

Responses

  • 200: The revoked token. Returns ScimToken.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Groups the identity provider pushed#

GET /v2/organizations/{org_id}/scim/groups · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). For picking groups in the role mapping editor.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/scim/groups"

Responses

  • 200: Groups by name.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Service provider configuration#

GET /scim/v2/ServiceProviderConfig · Auth: SCIM token · RevenueDot extension

PATCH, filters (at most 200 results) and ETags are supported. Bulk, sorting and password changes are not.

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/ServiceProviderConfig" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: RFC 7643 §5.
  • 401: No token, or a revoked or unknown one. Returns ScimError.

Resource types (User, Group)#

GET /scim/v2/ResourceTypes · Auth: SCIM token · RevenueDot extension

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/ResourceTypes" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: A ListResponse of User and Group. Returns ScimListResponse.
  • 401: No token, or a revoked or unknown one. Returns ScimError.

One resource type#

GET /scim/v2/ResourceTypes/{name} · Auth: SCIM token · RevenueDot extension

Path parameters

Name Type Required Description
name string yes User or Group.

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/ResourceTypes/$NAME" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: The resource type.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.

Schemas (User, Group, enterprise User)#

GET /scim/v2/Schemas · Auth: SCIM token · RevenueDot extension

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Schemas" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

One schema#

GET /scim/v2/Schemas/{id} · Auth: SCIM token · RevenueDot extension

Path parameters

Name Type Required Description
id string yes Schema URN.

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Schemas/$ID" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: The schema.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.

List or find users#

GET /scim/v2/Users · Auth: SCIM token · RevenueDot extension

Okta and Entra look a user up with filter=userName eq "..." before creating them.

Query parameters

Name Type Required Description
filter string no RFC 7644 filter: eq ne co sw ew pr gt ge lt le, and, or, not, parentheses and value paths such as emails[type eq "work"].value.
startIndex integer no 1-based.
count integer no Page size, at most 200.
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Users" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: A ListResponse of Users. Returns ScimListResponse.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "totalResults": 1,
  "startIndex": 1,
  "itemsPerPage": 1,
  "Resources": [
    {
      "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
      ],
      "id": "scu_9x2k4m8q1z7a3b5c",
      "externalId": "00u1a2b3c4d5",
      "userName": "sam@acme.com",
      "name": {
        "givenName": "Sam",
        "familyName": "Lee"
      },
      "emails": [
        {
          "value": "sam@acme.com",
          "type": "work",
          "primary": true
        }
      ],
      "active": true,
      "groups": [
        {
          "value": "scg_4k8m2q9x1z7a3b5c",
          "display": "RevenueDot Support"
        }
      ],
      "meta": {
        "resourceType": "User",
        "created": "2026-10-01T09:12:00.000Z",
        "lastModified": "2026-10-01T09:12:00.000Z",
        "location": "https://app.revenuedot.app/scim/v2/Users/scu_9x2k4m8q1z7a3b5c",
        "version": "W/\"1\""
      }
    }
  ]
}

Create a user#

POST /scim/v2/Users · Auth: SCIM token · RevenueDot extension

The email (primary, else work, else first address, else an email-shaped userName) must be on a domain the organization verified. An existing RevenueDot account with that address is linked; otherwise an account without a password is created. The person becomes an active organization member and their group role mappings apply. password is ignored.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Request body (application/scim+json)

Field Type Required Description
schemas array of string no
id string no SCIM user id (scu_...).
externalId string no The identity provider's id.
userName string yes Unique in the organization, without regard to case.
name object no
name.formatted string no
name.givenName string no
name.familyName string no
displayName string no
emails array of object no The primary address (else the work address, else the first) is the account's email. It must be on a verified domain.
emails[].value string no
emails[].type string no
emails[].primary boolean no
active boolean no False deprovisions the person.
groups array of object no Read only.
groups[].value string no SCIM group id.
groups[].display string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no Weak ETag such as W/"3".

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/scim/v2/Users" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"sam@acme.com","name":{"givenName":"Sam","familyName":"Lee"},"emails":[{"value":"sam@acme.com","type":"work","primary":true}],"active":true}'

Responses

  • 201: The user. Returns ScimUser.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 201 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "id": "scu_9x2k4m8q1z7a3b5c",
  "externalId": "00u1a2b3c4d5",
  "userName": "sam@acme.com",
  "name": {
    "givenName": "Sam",
    "familyName": "Lee"
  },
  "emails": [
    {
      "value": "sam@acme.com",
      "type": "work",
      "primary": true
    }
  ],
  "active": true,
  "groups": [
    {
      "value": "scg_4k8m2q9x1z7a3b5c",
      "display": "RevenueDot Support"
    }
  ],
  "meta": {
    "resourceType": "User",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Users/scu_9x2k4m8q1z7a3b5c",
    "version": "W/\"1\""
  }
}

Get a user#

GET /scim/v2/Users/{id} · Auth: SCIM token · RevenueDot extension

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-None-Match string no Optional. Answers 304 when the ETag still matches.

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Users/$ID" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: The user. Returns ScimUser.
  • 304: Not modified.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "id": "scu_9x2k4m8q1z7a3b5c",
  "externalId": "00u1a2b3c4d5",
  "userName": "sam@acme.com",
  "name": {
    "givenName": "Sam",
    "familyName": "Lee"
  },
  "emails": [
    {
      "value": "sam@acme.com",
      "type": "work",
      "primary": true
    }
  ],
  "active": true,
  "groups": [
    {
      "value": "scg_4k8m2q9x1z7a3b5c",
      "display": "RevenueDot Support"
    }
  ],
  "meta": {
    "resourceType": "User",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Users/scu_9x2k4m8q1z7a3b5c",
    "version": "W/\"1\""
  }
}

Replace a user#

PUT /scim/v2/Users/{id} · Auth: SCIM token · RevenueDot extension

active: false deprovisions: the person loses every membership in the organization's projects and every session ends. active: true again restores group-mapped access. A new email, or a reactivation, must be on a verified domain. The organization's last owner cannot be deactivated (400).

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Request body (application/scim+json)

Field Type Required Description
schemas array of string no
id string no SCIM user id (scu_...).
externalId string no The identity provider's id.
userName string yes Unique in the organization, without regard to case.
name object no
name.formatted string no
name.givenName string no
name.familyName string no
displayName string no
emails array of object no The primary address (else the work address, else the first) is the account's email. It must be on a verified domain.
emails[].value string no
emails[].type string no
emails[].primary boolean no
active boolean no False deprovisions the person.
groups array of object no Read only.
groups[].value string no SCIM group id.
groups[].display string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no Weak ETag such as W/"3".

Example request

Shell
curl -s -X PUT "$REVENUEDOT_URL/scim/v2/Users/$ID" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"sam@acme.com","name":{"givenName":"Sam","familyName":"Lee"},"emails":[{"value":"sam@acme.com","type":"work","primary":true}],"active":true}'

Responses

  • 200: The user. Returns ScimUser.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "id": "scu_9x2k4m8q1z7a3b5c",
  "externalId": "00u1a2b3c4d5",
  "userName": "sam@acme.com",
  "name": {
    "givenName": "Sam",
    "familyName": "Lee"
  },
  "emails": [
    {
      "value": "sam@acme.com",
      "type": "work",
      "primary": true
    }
  ],
  "active": true,
  "groups": [
    {
      "value": "scg_4k8m2q9x1z7a3b5c",
      "display": "RevenueDot Support"
    }
  ],
  "meta": {
    "resourceType": "User",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Users/scu_9x2k4m8q1z7a3b5c",
    "version": "W/\"1\""
  }
}

Change a user#

PATCH /scim/v2/Users/{id} · Auth: SCIM token · RevenueDot extension

RFC 7644 PATCH. Also accepts Okta's replace without a path and Entra's capitalised op values, "False" strings and dotted keys. Same effects as PUT.

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Request body (application/scim+json)

Field Type Required Description
schemas array of string yes Must contain urn:ietf:params:scim:api:messages:2.0:PatchOp.
Operations array of object yes
Operations[].op string yes add, replace or remove; any case.
Operations[].path string no Optional for add and replace. Value filters such as emails[type eq "work"].value work.
Operations[].value object no

Example request

Shell
curl -s -X PATCH "$REVENUEDOT_URL/scim/v2/Users/$ID" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"replace","path":"active","value":false}]}'

Responses

  • 200: The user. Returns ScimUser.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User"
  ],
  "id": "scu_9x2k4m8q1z7a3b5c",
  "externalId": "00u1a2b3c4d5",
  "userName": "sam@acme.com",
  "name": {
    "givenName": "Sam",
    "familyName": "Lee"
  },
  "emails": [
    {
      "value": "sam@acme.com",
      "type": "work",
      "primary": true
    }
  ],
  "active": true,
  "groups": [
    {
      "value": "scg_4k8m2q9x1z7a3b5c",
      "display": "RevenueDot Support"
    }
  ],
  "meta": {
    "resourceType": "User",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Users/scu_9x2k4m8q1z7a3b5c",
    "version": "W/\"1\""
  }
}

Delete a user#

DELETE /scim/v2/Users/{id} · Auth: SCIM token · RevenueDot extension

Deprovisions the person like active: false, then deletes the SCIM user. The RevenueDot account and its audit history stay.

Path parameters

Name Type Required Description
id string yes The SCIM id.

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/scim/v2/Users/$ID" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 204: Deleted.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.

List or find groups#

GET /scim/v2/Groups · Auth: SCIM token · RevenueDot extension

Query parameters

Name Type Required Description
filter string no RFC 7644 filter: eq ne co sw ew pr gt ge lt le, and, or, not, parentheses and value paths such as emails[type eq "work"].value.
startIndex integer no 1-based.
count integer no Page size, at most 200.
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Groups" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: A ListResponse of Groups. Returns ScimListResponse.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "totalResults": 1,
  "startIndex": 1,
  "itemsPerPage": 1,
  "Resources": [
    {
      "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:Group"
      ],
      "id": "scg_4k8m2q9x1z7a3b5c",
      "displayName": "RevenueDot Support",
      "members": [
        {
          "value": "scu_9x2k4m8q1z7a3b5c",
          "display": "Sam Lee",
          "type": "User"
        }
      ],
      "meta": {
        "resourceType": "Group",
        "created": "2026-10-01T09:12:00.000Z",
        "lastModified": "2026-10-01T09:12:00.000Z",
        "location": "https://app.revenuedot.app/scim/v2/Groups/scg_4k8m2q9x1z7a3b5c",
        "version": "W/\"1\""
      }
    }
  ]
}

Create a group#

POST /scim/v2/Groups · Auth: SCIM token · RevenueDot extension

Members must be SCIM Users of the organization (400 otherwise). Group role mappings with this name apply to the members at once.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Request body (application/scim+json)

Field Type Required Description
schemas array of string no
id string no SCIM group id (scg_...).
externalId string no
displayName string yes Unique in the organization. Role mappings match it.
members array of object no
members[].value string no SCIM user id.
members[].display string no
members[].type string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no

Example request

Shell
curl -s -X POST "$REVENUEDOT_URL/scim/v2/Groups" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],"displayName":"RevenueDot Support","members":[{"value":"scu_9x2k4m8q1z7a3b5c"}]}'

Responses

  • 201: The group. Returns ScimGroup.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 201 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "id": "scg_4k8m2q9x1z7a3b5c",
  "displayName": "RevenueDot Support",
  "members": [
    {
      "value": "scu_9x2k4m8q1z7a3b5c",
      "display": "Sam Lee",
      "type": "User"
    }
  ],
  "meta": {
    "resourceType": "Group",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Groups/scg_4k8m2q9x1z7a3b5c",
    "version": "W/\"1\""
  }
}

Get a group#

GET /scim/v2/Groups/{id} · Auth: SCIM token · RevenueDot extension

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-None-Match string no Optional. Answers 304 when the ETag still matches.

Example request

Shell
curl -s "$REVENUEDOT_URL/scim/v2/Groups/$ID" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 200: The group. Returns ScimGroup.
  • 304: Not modified.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "id": "scg_4k8m2q9x1z7a3b5c",
  "displayName": "RevenueDot Support",
  "members": [
    {
      "value": "scu_9x2k4m8q1z7a3b5c",
      "display": "Sam Lee",
      "type": "User"
    }
  ],
  "meta": {
    "resourceType": "Group",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Groups/scg_4k8m2q9x1z7a3b5c",
    "version": "W/\"1\""
  }
}

Replace a group#

PUT /scim/v2/Groups/{id} · Auth: SCIM token · RevenueDot extension

Replaces the name and the member list. Access is re-applied for everyone who joined or left, and for every member after a rename.

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Request body (application/scim+json)

Field Type Required Description
schemas array of string no
id string no SCIM group id (scg_...).
externalId string no
displayName string yes Unique in the organization. Role mappings match it.
members array of object no
members[].value string no SCIM user id.
members[].display string no
members[].type string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no

Example request

Shell
curl -s -X PUT "$REVENUEDOT_URL/scim/v2/Groups/$ID" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:Group"],"displayName":"RevenueDot Support","members":[{"value":"scu_9x2k4m8q1z7a3b5c"}]}'

Responses

  • 200: The group. Returns ScimGroup.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "id": "scg_4k8m2q9x1z7a3b5c",
  "displayName": "RevenueDot Support",
  "members": [
    {
      "value": "scu_9x2k4m8q1z7a3b5c",
      "display": "Sam Lee",
      "type": "User"
    }
  ],
  "meta": {
    "resourceType": "Group",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Groups/scg_4k8m2q9x1z7a3b5c",
    "version": "W/\"1\""
  }
}

Change a group#

PATCH /scim/v2/Groups/{id} · Auth: SCIM token · RevenueDot extension

Add or remove members (remove with members[value eq "..."]), or rename.

Path parameters

Name Type Required Description
id string yes The SCIM id.

Query parameters

Name Type Required Description
attributes string no Comma-separated attributes to return.
excludedAttributes string no Comma-separated attributes to leave out (members on Groups is common).

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Request body (application/scim+json)

Field Type Required Description
schemas array of string yes Must contain urn:ietf:params:scim:api:messages:2.0:PatchOp.
Operations array of object yes
Operations[].op string yes add, replace or remove; any case.
Operations[].path string no Optional for add and replace. Value filters such as emails[type eq "work"].value work.
Operations[].value object no

Example request

Shell
curl -s -X PATCH "$REVENUEDOT_URL/scim/v2/Groups/$ID" -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" -d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"add","path":"members","value":[{"value":"scu_9x2k4m8q1z7a3b5c"}]}]}'

Responses

  • 200: The group. Returns ScimGroup.
  • 400: The request, filter or PATCH is invalid. Returns ScimError.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 409: The userName, email or group name is taken. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.
  • 413: The body is larger than 1 MB. Returns ScimError.

Example 200 response:

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group"
  ],
  "id": "scg_4k8m2q9x1z7a3b5c",
  "displayName": "RevenueDot Support",
  "members": [
    {
      "value": "scu_9x2k4m8q1z7a3b5c",
      "display": "Sam Lee",
      "type": "User"
    }
  ],
  "meta": {
    "resourceType": "Group",
    "created": "2026-10-01T09:12:00.000Z",
    "lastModified": "2026-10-01T09:12:00.000Z",
    "location": "https://app.revenuedot.app/scim/v2/Groups/scg_4k8m2q9x1z7a3b5c",
    "version": "W/\"1\""
  }
}

Delete a group#

DELETE /scim/v2/Groups/{id} · Auth: SCIM token · RevenueDot extension

Access that came from the group's role mappings is removed from its former members.

Path parameters

Name Type Required Description
id string yes The SCIM id.

Headers

Name Type Required Description
If-Match string no Optional. The ETag you read; a changed resource answers 412.

Example request

Shell
curl -s -X DELETE "$REVENUEDOT_URL/scim/v2/Groups/$ID" -H "Authorization: Bearer $SCIM_TOKEN"

Responses

  • 204: Deleted.
  • 401: No token, or a revoked or unknown one. Returns ScimError.
  • 404: Not found in the token's organization. Returns ScimError.
  • 412: If-Match does not match the current version. Returns ScimError.

Compliance exports#

The audit log and an access review as CSV or JSON, signed with Ed25519. See Audit retention and exports.

The public key exports are signed with#

GET /v2/organizations/{org_id}/exports/public_key · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise).

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/exports/public_key"

Responses

  • 200: The key.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Example 200 response:

JSON
{
  "object": "export_signing_key",
  "algorithm": "Ed25519",
  "public_key": "kQ3s0x8b1m5Zt2Wq7yJcVhE9nR4uLpA6fG0dK3oT1sY=",
  "key_id": "4be1c0f29a7d3e58",
  "signs": true
}

Download a signed audit log or access review#

GET /v2/organizations/{org_id}/exports/{kind} · Auth: dashboard session · RevenueDot extension

Organization owners and admins. When the organization requires single sign-on, people on its verified domains other than owners need a session that began with its SSO (403 otherwise). At most 200,000 rows per file; more answers 400, so choose a shorter date range. CSV cells that start with =, +, -, @, a tab or a carriage return get a leading apostrophe. Each download is recorded in the organization audit log as compliance_export_created with its SHA-256.

Path parameters

Name Type Required Description
org_id string yes Organization id (org_...).
kind audit_logs, access_review yes audit_logs: the organization log and its projects' logs, oldest first. access_review: one row per person per organization project, plus members without project access.

Query parameters

Name Type Required Description
format csv, json no Default csv.
start_time integer no Audit logs only: entries at or after this time (epoch milliseconds).
end_time integer no Audit logs only: entries before this time (epoch milliseconds).

Example request

Shell
curl -s "$REVENUEDOT_URL/v2/organizations/$ORG_ID/exports/$KIND"

Responses

  • 200: The file, as an attachment.
  • 400: The request is invalid. Returns V2Error.
  • 401: No API key, or an unknown one. Returns V2Error.
  • 403: The key lacks a permission, or a public key was used. Returns V2Error.
  • 404: Not found in this project (another project's ids also answer 404). Returns V2Error.

Objects#

The shapes the operations above send and return.

CustomRole#

Field Type Required Description
object "custom_role" yes
id string yes Role id (role_...).
name string yes Unique in the organization.
description string or null no
scopes array of string yes API v2 scopes from GET /v2/organizations/{org_id}/scopes, sorted.
project_id string or null no The one project the role is for. Null: every project of the organization.
member_count integer no Project memberships that use the role.
created_at integer no Creation time. Epoch milliseconds.
updated_at integer no Last change. Epoch milliseconds.

EnterpriseStatus#

Field Type Required Description
object "enterprise" yes
mode licensed, development, invalid yes licensed: a valid licence key. development: REVENUEDOT_EE_DEV=true, for development and testing only. invalid: a key that failed or expired more than 14 days ago; no feature is on.
features array of organizations, custom_roles, sso, scim, data_location, audit_retention, compliance_exports yes The features that are on.
licensee string or null no Who the licence is for.
expires_at integer or null no When the licence expires. Features keep working for 14 days after it. Epoch milliseconds, or null.
message string or null no Why the licence is invalid, or a renewal warning.

Organization#

Field Type Required Description
object "organization" yes
id string yes Organization id (org_...).
name string yes
your_role owner, admin, member yes Your role in the organization.
region us, eu yes Default data location for the organization's projects.
region_name string no United States or European Union.
selectable_regions array of us, eu no Regions this server accepts. A self-hosted server accepts both. A deployment that enforces regions accepts only its own.
region_enforced boolean no True when this deployment refuses requests for projects stored in another region.
audit_retention_days integer or null no Days audit log rows are kept (30 to 3650). Null keeps them forever.
sso_enforced boolean no Whether people on the organization's verified domains must sign in with single sign-on.
seats object no
seats.purchased integer or null no Seats bought. Recorded, not enforced.
seats.used integer no People who are active members or members of one of the organization's projects.
billing_email string or null no
member_count integer no Active members.
project_count integer no
features array of string no The enterprise features this server's licence turns on.
created_at integer no Creation time. Epoch milliseconds.
updated_at integer no Last change. Epoch milliseconds.

OrganizationAuditLog#

Field Type Required Description
object "organization_audit_log" yes
id string yes
action string yes For example member_added, sso_sign_in, scim_user_deactivated, audit_logs_purged.
actor object yes
actor.type user, scim, sso, system no
actor.id string or null no User id, SCIM token id or SSO connection id.
actor.email string or null no The user's email.
target object yes
target.type string no
target.id string or null no
data object no Details. Never secrets or SAML assertions.
occurred_at integer yes When it happened. Epoch milliseconds.

OrganizationMember#

Field Type Required Description
object "organization_member" yes
user_id string yes
email string yes
name string or null no
role owner, admin, member yes
source manual, sso, scim, project yes How the person joined: added by hand, first sign-in with SSO, SCIM, or through a project of the organization.
active boolean yes False after SCIM deprovisioning.
sso_groups array of string no The groups the identity provider sent at the last SSO sign-in.
last_sso_at integer or null no The last SSO sign-in. Epoch milliseconds, or null.
password_sign_in boolean no Whether the account has a password.
created_at integer no When the person joined. Epoch milliseconds.

OrganizationProject#

Field Type Required Description
object "organization_project" yes
id string yes Project id.
name string yes
region us, eu yes
region_name string no
member_count integer no Project members.
your_role string or null no Your role in the project, or null.
added_at integer no When the project joined the organization. Epoch milliseconds.

OrganizationProjectMember#

Field Type Required Description
object "project_member" yes
user_id string yes
email string no
name string or null no
role string yes admin, developer, viewer or a custom role id (role_...).
role_name string yes Admin, Developer, Viewer, the custom role's name, or "No access (role removed)".
source manual, org, idp no org: an organization owner or admin. idp: a group role mapping. manual: set by hand; provisioning leaves it alone.

RoleMapping#

Field Type Required Description
object "role_mapping" yes
id string yes Mapping id (map_...).
group string yes Group name, matched without regard to case against SCIM group names and the SSO groups attribute or claim.
project_id string yes
project_name string or null no
role string yes admin, developer, viewer or a custom role id.
role_name string no
created_at integer no Creation time. Epoch milliseconds.

ScimError#

RFC 7644 error body, sent as application/scim+json.

Field Type Required Description
schemas array of string yes
status string yes The HTTP status as a string.
scimType uniqueness, invalidFilter, invalidValue, invalidSyntax, invalidPath, noTarget, mutability, tooMany no
detail string yes What went wrong.

ScimGroup#

A SCIM 2.0 Group. Members are SCIM Users of the organization; nested groups are refused.

Field Type Required Description
schemas array of string yes
id string yes SCIM group id (scg_...).
externalId string no
displayName string yes Unique in the organization. Role mappings match it.
members array of object no
members[].value string no SCIM user id.
members[].display string no
members[].type string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no

ScimListResponse#

Field Type Required Description
schemas array of string yes
totalResults integer yes
startIndex integer yes 1-based.
itemsPerPage integer yes
Resources array of object yes

ScimPatchOp#

Field Type Required Description
schemas array of string yes Must contain urn:ietf:params:scim:api:messages:2.0:PatchOp.
Operations array of object yes
Operations[].op string yes add, replace or remove; any case.
Operations[].path string no Optional for add and replace. Value filters such as emails[type eq "work"].value work.
Operations[].value object no

ScimToken#

Field Type Required Description
object "scim_token" yes
id string yes Token id (sct_...).
name string yes
prefix string yes The first 13 characters, to tell tokens apart.
created_by string no User id.
created_at integer no Creation time. Epoch milliseconds.
last_used_at integer or null no Last request, to the minute. Epoch milliseconds, or null.
revoked_at integer or null no When it was revoked. Epoch milliseconds, or null.

ScimUser#

A SCIM 2.0 User (RFC 7643). Other attributes you send, such as phoneNumbers and the enterprise extension, are stored and returned.

Field Type Required Description
schemas array of string yes
id string yes SCIM user id (scu_...).
externalId string no The identity provider's id.
userName string yes Unique in the organization, without regard to case.
name object no
name.formatted string no
name.givenName string no
name.familyName string no
displayName string no
emails array of object no The primary address (else the work address, else the first) is the account's email. It must be on a verified domain.
emails[].value string no
emails[].type string no
emails[].primary boolean no
active boolean yes False deprovisions the person.
groups array of object no Read only.
groups[].value string no SCIM group id.
groups[].display string no
meta object no
meta.resourceType string no
meta.created string no
meta.lastModified string no
meta.location string no
meta.version string no Weak ETag such as W/"3".

SsoConnection#

Field Type Required Description
object "sso_connection" yes
id string yes Connection id (ssoc_...).
org_id string yes
kind saml, oidc yes
name string yes
enabled boolean yes Sign-ins work only when true. New connections start off.
jit boolean yes Create accounts and organization memberships at first sign-in. Default true.
saml object no
saml.idp_entity_id string no The identity provider's entity ID (Issuer).
saml.idp_sso_url string no The identity provider's sign-in URL for the HTTP-Redirect binding. https on RevenueDot Cloud.
saml.idp_certificates array of string no 1 to 5 signing certificates as PEM. Several while the identity provider rotates its certificate.
saml.allow_idp_initiated boolean no Accept sign-ins started from the identity provider's app dashboard. Default false.
saml.email_attribute string or null no Attribute that holds the email address. Null: email, mail, emailaddress, Microsoft's emailaddress claim, urn:oid:0.9.2342.19200300.100.1.3, else an email-shaped NameID.
saml.first_name_attribute string or null no Attribute for the first name. Null: common names such as givenname and firstname.
saml.last_name_attribute string or null no Attribute for the last name. Null: common names such as sn and surname.
saml.groups_attribute string or null no Attribute that lists the person's groups. Null: groups or Microsoft's groups claim.
oidc object no
oidc.issuer string no The issuer URL. RevenueDot reads <issuer>/.well-known/openid-configuration.
oidc.client_id string no The client ID registered with the identity provider.
oidc.scopes array of string no Default openid email profile. openid is always added.
oidc.groups_claim string or null no The ID token claim that lists the person's groups. Null: groups are not read.
oidc.has_client_secret boolean no Whether a client secret is stored. The secret itself is never returned.
sp object yes The values to enter in the identity provider, built from REVENUEDOT_PUBLIC_URL or the request's address.
sp.entity_id string no SAML: the entity ID (audience) to enter in the identity provider.
sp.acs_url string no SAML: the assertion consumer service URL.
sp.metadata_url string no SAML: RevenueDot's service provider metadata.
sp.redirect_uri string no OpenID Connect: the redirect URI to register.
sp.start_url string yes A link that starts a sign-in with this connection.
created_at integer no Creation time. Epoch milliseconds.
updated_at integer no Last change. Epoch milliseconds.

SsoDomain#

Field Type Required Description
object "sso_domain" yes
domain string yes
verified boolean yes
verified_at integer or null no When the TXT record was first found. Epoch milliseconds, or null.
txt_record object yes
txt_record.type "TXT" no
txt_record.name string no _revenuedot-sso.<domain>
txt_record.value string no revenuedot-sso-verification=<token>
last_checked_at integer or null no The last check. Epoch milliseconds, or null.
last_error string or null no Why the last check failed.
created_at integer no When it was added. Epoch milliseconds.

V2Error#

Field Type Required Description
object "error" yes
type parameter_error, resource_already_exists, resource_missing, idempotency_error, rate_limit_error, authentication_error, authorization_error, store_error, server_error, resource_locked_error, unprocessable_entity_error, invalid_request, entity_references_archived_entities yes
message string yes What went wrong.
param string no The request field at fault, when there is one.
doc_url string yes Link to the error's section of the errors page.
retryable boolean yes True when retrying the same request can succeed.