Skip to content
Preview. The endpoints on this page are illustrative and are likely to change as they move toward general availability. Documentation is published in advance so you can start shaping your integration; treat request and response details as subject to revision.

Organizations

Read and update organization records — the top-level tenant boundary. Every token is scoped to exactly one org (via API Management-injected X-Cirrus-Org-Id), so "list orgs" isn't a partner-facing operation — you either read the org your token belongs to, or you pass an orgId that must match.

OperationScope required
Read (GET)organizations:read
Updateorganizations:write

PATCH /organizations/{orgId} requires Idempotency-Key and If-Match (from a prior GET's ETag).

/organizations/me returns the org the token belongs to. /me refers to the token's identity, not a user — every v1alpha1 token is org-scoped, so the token's identity is the org. When per-user OAuth ships, /me will resolve the authorising user on the users endpoint; the URL convention is consistent across both.

Endpoints on this page

MethodEndpointDescription
GET/api/v1alpha1/organizations/meThe org the caller's token belongs to. Details ↓
GET/api/v1alpha1/organizations/{orgId}Fetch one organization. {orgId} must equal the token's org context. Details ↓
GET/api/v1alpha1/organizations/me/entitlementsFeature entitlements — which Cirrus features the org has licensed, plus seat counts. Details ↓
PATCH/api/v1alpha1/organizations/{orgId}Partial-merge update. Name, industry, primary email domain. Details ↓

Get my organization

GET /api/v1alpha1/organizations/me

The org the token belongs to. Partners often don't want to hardcode the org_... id.

Response

Identical shape to GET /organizations/{orgId}. Includes an ETag header.

  • /me returns the resource directly, not an HTTP redirect. Saves a round trip vs a 302.
  • A token that isn't org-scoped returns 401 token-not-org-scoped. Should never happen in v1alpha1 (all tokens are org-scoped), but the contract is explicit for future auth models.

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me",
    headers={"X-Cirrus-Api-Key": token},
)
response.raise_for_status()
org = response.json()
etag = response.headers["ETag"]
csharp
using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var response = await client.GetAsync(
    "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me");
response.EnsureSuccessStatusCode();
var org = await response.Content.ReadAsStringAsync();
var etag = response.Headers.ETag?.Tag;

Get an organization

GET /api/v1alpha1/organizations/{orgId}

{orgId} must equal the token's org context; otherwise 404 organization-not-found (cross-org access never leaks).

Response

Response headers:

HeaderValueNotes
ETagW/"<version>"Required on subsequent PATCH via If-Match.

See the Organizationmodel for the full field reference.

  • administrator is a single user — the org's contractual owner (billing contact, signatory). Other users with the Administrator role show up via GET /users?role=Administrator.
  • emailDomains[] returns the domain string only, not per-domain verification-status flags.

Errors

  • 404 organization-not-foundorgId doesn't equal the token's org context

bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/organizations/org_01H8YKQ2N9ACME" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

org_id = "org_01H8YKQ2N9ACME"
response = requests.get(
    f"https://altus.cirrusinsight.com/api/v1alpha1/organizations/{org_id}",
    headers={"X-Cirrus-Api-Key": token},
)
response.raise_for_status()
org = response.json()
etag = response.headers["ETag"]
csharp
using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var orgId = "org_01H8YKQ2N9ACME";
var response = await client.GetAsync(
    $"https://altus.cirrusinsight.com/api/v1alpha1/organizations/{orgId}");
response.EnsureSuccessStatusCode();
var org = await response.Content.ReadAsStringAsync();
var etag = response.Headers.ETag?.Tag;
json
{
  "id": "org_...",
  "name": "Acme Corporation",
  "primaryEmailDomain": "acme.com",
  "emailDomains": ["acme.com", "acme.co.uk"],
  "administrator": {
    "userId": "usr_...",
    "displayName": "Sam Chen"
  },
  "industry": "SaaS",
  "employeeCount": 1250,
  "logoUrl": "https://cdn.example.com/orgs/org_....png",
  "sourceRefs": {
    "salesforce": {
      "orgId": "00D1U000000abcXYZ"
    }
  },
  "createdAt": "2024-03-15T00:00:00Z",
  "updatedAt": "2026-07-14T09:30:00Z"
}

Get entitlements

GET /api/v1alpha1/organizations/me/entitlements

Which Cirrus features the org has licensed. Separate sub-resource — different cache TTL (bill-driven, not profile-driven).

Response

Response headers:

HeaderValueNotes
Cache-Controlprivate, max-age=60Suggested client caching. Billing events are minute-scale, not real-time.
  • features is a fixed enum, not an open-ended map. New features get added with a documented available_since date; removed features stay as false for one major version before being retired.
  • seats is exposed even though billing detail isn't, because the invite-flow error (seat-limit-exceeded) needs a way for partners to preflight. Explicit seats.available makes the flow honest.
  • licenseTier.slug is coarse-grained: free, starter, professional, enterprise. Partners key on slug. For per-feature capability checks, use features.{name} — don't infer from tier.
  • No trial-end date. Partners running upsell flows use licenseTier.slug === "free" or "starter" as their signal.

Errors

None beyond the standard 401 / 403 / 429. The endpoint always has an answer for a valid caller.


bash
curl -s "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me/entitlements" \
  -H "X-Cirrus-Api-Key: $TOKEN"
python
import requests

response = requests.get(
    "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me/entitlements",
    headers={"X-Cirrus-Api-Key": token},
)
response.raise_for_status()
entitlements = response.json()
csharp
using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var response = await client.GetAsync(
    "https://altus.cirrusinsight.com/api/v1alpha1/organizations/me/entitlements");
response.EnsureSuccessStatusCode();
var entitlements = await response.Content.ReadAsStringAsync();
json
{
  "orgId": "org_...",
  "features": {
    "smartScheduling": true,
    "teamCalendarScheduling": true,
    "replyTracking": true,
    "emailBlast": false,
    "cortexApp": true,
    "meetingAi": true
  },
  "seats": {
    "total": 25,
    "used": 18,
    "available": 7
  },
  "licenseTier": {
    "slug": "professional",
    "name": "Professional"
  },
  "asOf": "2026-08-20T15:00:00Z"
}

Update an organization

PATCH /api/v1alpha1/organizations/{orgId}

Update org display name, industry, primary email domain. Requires organizations:write, Idempotency-Key, and If-Match.

Mutable fields

FieldTypeNotes
namestringDisplay name. Max 200 chars.
primaryEmailDomainstringMust be an already-verified domain from emailDomains[]. Rotates which domain is used for invitation flows.
industrystringFree-text, aligned with Cortex's account industry taxonomy.
employeeCountnumber1–1,000,000.

Response

The updated org record — same shape as GET /organizations/{orgId}. Fresh ETag header.

  • Verifying a new email domain is out of scope for PATCH. Adding a domain requires DNS verification (interactive TXT-record challenge). PATCH can only rotate the primary domain among already-verified entries.
  • administrator is not mutable via PATCH. Transferring org ownership requires the outgoing admin's consent + the incoming admin's acceptance — dashboard-only in v1alpha1.
  • No writes to sourceRefs. External-system links are managed through the integration-connection flows, not this PATCH.

Errors

StatustypeWhen
400invalid-fieldUnknown field or invalid value
400email-domain-not-verifiedprimaryEmailDomain isn't in the org's verified domain list
403write-scope-requiredToken has organizations:read but not organizations:write
404organization-not-foundorgId doesn't equal the token's org context
412precondition-failedIf-Match doesn't match current version
422idempotency-key-conflictStandard replay violation
bash
curl -s -X PATCH "https://altus.cirrusinsight.com/api/v1alpha1/organizations/org_01H8YKQ2N9ACME" \
  -H "X-Cirrus-Api-Key: $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'If-Match: W/"12"' \
  -d '{
    "name": "Acme Global, Inc.",
    "industry": "Enterprise Software",
    "employeeCount": 1400
  }'
python
import requests
import uuid

org_id = "org_01H8YKQ2N9ACME"
response = requests.patch(
    f"https://altus.cirrusinsight.com/api/v1alpha1/organizations/{org_id}",
    headers={
        "X-Cirrus-Api-Key": token,
        "Idempotency-Key": str(uuid.uuid4()),
        "If-Match": etag,
    },
    json={
        "name": "Acme Global, Inc.",
        "industry": "Enterprise Software",
        "employeeCount": 1400,
    },
)
response.raise_for_status()
updated = response.json()
csharp
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Cirrus-Api-Key", token);

var orgId = "org_01H8YKQ2N9ACME";
var body = new
{
    name = "Acme Global, Inc.",
    industry = "Enterprise Software",
    employeeCount = 1400,
};

var request = new HttpRequestMessage(HttpMethod.Patch,
    $"https://altus.cirrusinsight.com/api/v1alpha1/organizations/{orgId}")
{
    Content = new StringContent(
        JsonSerializer.Serialize(body),
        Encoding.UTF8,
        "application/json"),
};
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Headers.Add("If-Match", etag);

var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var updated = await response.Content.ReadAsStringAsync();
  • Organization — the full field reference.
  • User — every user has an orgId that resolves to an Organization.

Raleigh, NC — a Cirruspath, Inc. company