Claude Platform Docs
AdminSecurity posture

Security posture results reference

Look up the Compliance API endpoint that returns an organization’s current Security posture results: the request, the response fields, what each status means, and the errors.

This endpoint returns an entry for most of an organization’s security controls, evaluated at the time of the request, with the Security posture attestation that the response shows for each control. You need a Compliance Access Key that covers the organization, with the read:compliance_org_data or read:org_audit scope; Security posture availability says which organizations can be read.

Request

Send a GET request to /v1/compliance/organizations/{organization_id}/security_posture. Each call reads one organization, and the response is not paginated.

cURL
curl --fail-with-body -sS \
  "https://api.anthropic.com/v1/compliance/organizations/91012d09-e48b-438e-a489-1bebfd8fa6f9/security_posture" \
  -H "x-api-key: $ANTHROPIC_COMPLIANCE_ACCESS_KEY" \
  -H "anthropic-version: 2026-10-21"
ItemRule
organization_idThe uuid of a linked organization from List organizations; any other value returns 404.
KeyA key for the parent organization can name any linked organization, and a key for a single organization can name only that organization.
anthropic-versionRequired; a request without it returns 400.
Query parametersNone; a request with any query parameter returns 400.

Response

The following abridged example shows four of the controls that a response can contain. It is the response to a key that holds read:compliance_org_data and read:compliance_user_data.

Response
{
  "type": "security_posture",
  "organization_id": "91012d09-e48b-438e-a489-1bebfd8fa6f9",
  "evaluated_at": "2027-02-09T09:00:02.417305Z",
  "comments_status": "not_enabled",
  "controls": [
    {
      "id": "sso_enabled",
      "display_name": "Single sign-on (SSO)",
      "section": "identity_access",
      "setting_name": "sso_enabled",
      "status": "passed",
      "rating": "passed",
      "current_value": "On",
      "desired_state": "On",
      "attestation": null
    },
    {
      "id": "directory_sync_enabled",
      "display_name": "Directory sync (SCIM)",
      "section": "identity_access",
      "setting_name": "directory_sync_enabled",
      "status": "failed_check_accepted_risk",
      "rating": "passed",
      "current_value": "Off",
      "desired_state": "On",
      "attestation": {
        "state": "in_force",
        "attested_at": "2026-10-20T15:04:00.220114Z",
        "comment": null,
        "attested_by": {
          "type": "user_actor",
          "user_id": "user_01WxYzAbCdEfGhJkMnPqRsTu"
        }
      }
    },
    {
      "id": "allowed_invite_domains",
      "display_name": "Allowed email domains",
      "section": "identity_access",
      "setting_name": "allowed_invite_domains",
      "status": "descriptive",
      "rating": "descriptive",
      "current_value": "example.com",
      "desired_state": null,
      "attestation": null
    },
    {
      "id": "oauth_conditional_access",
      "display_name": "OAuth conditional access on connected SaaS",
      "section": "connectors_integrations",
      "setting_name": null,
      "status": "not_attested",
      "rating": "not_attested",
      "current_value": null,
      "desired_state": "Completed",
      "attestation": {
        "state": "review_due",
        "attested_at": "2026-11-02T09:30:00.008771Z",
        "comment": null,
        "attested_by": {
          "type": "user_actor",
          "user_id": "user_01AbCdEfGhJkLmNpQrStUvWx"
        }
      }
    }
  ]
}

Every field is always present, and a field with no value is null, never left out. A time has either no fractional digits or six, so compare times as times, not as strings.

Top-level fields

FieldTypeDescription
typestringAlways security_posture.
organization_idstringThe organization’s UUID.
evaluated_atstring (RFC 3339, UTC)The time at which every control was evaluated.
comments_statusstringWhether attestation comments were read; see Who attested, and comments.
controlsarray of objectsThe organization’s controls, never empty.

controls[] fields

FieldTypeDescription
idstringThe control’s identifier, which is the same for every organization and never changes.
display_namestringThe control’s display name, as English display text whose wording can change.
sectionstringThe section that the control belongs to, one of the ten listed after this table; more values can be added, so treat an unknown one as a section of its own.
setting_namestring or nullThe name of the entry in the organization’s effective settings that this control reads; null when it reads no such entry.
statusstringThe reason for the control’s result; see Status values.
ratingstringThe control’s result, which follows from status; see Status values.
current_valuestring or nullThe current value, as English display text whose wording can change; null on a manual control or when no value was read.
desired_statestring or nullThe recommended value, as English display text whose wording can change; null when there is none for this organization.
attestationobject or nullThe attestation that the response shows, also while it is not in effect; null while status is descriptive, not_applicable, or not_evaluated, and in these cases.

section is one of identity_access, data_privacy, capabilities, connectors_integrations, chats_desktop_mdm, cowork_admin_console, cowork_desktop_mdm, claude_code_admin_console, claude_code_managed_settings, and healthy_adoption.

To compare values in code, look up setting_name in the effective settings of the same organization. The lookup can find nothing, and two controls can share one setting_name.

attestation fields

FieldTypeDescription
statestringWhether the attestation is in effect; see Attestation states.
attested_atstring (RFC 3339, UTC)When the attestation was made.
commentstring or nullThe comment saved with the attestation, of at most 2,000 characters; null if there is none or if comments_status is not available.
attested_byobject or nullThe person who attested; null when the key holds neither read:compliance_user_data nor read:org_audit, when that person’s account has been deleted or is being deleted, or when the endpoint does not return who attested for the organization.

attested_by fields

FieldTypeDescription
typestringAlways user_actor.
user_idstringThe user’s ID, which starts with user_.

Status values

status gives the reason for a control’s result, and each status has one rating.

statusKind of controlMeaningratingOn the page
passedautomaticThe current value meets the recommended value.passedPassed
matches_profileautomaticThe current value equals the recommended value.passedPassed
exceeds_baselineautomaticThe current value is stricter than the recommended value.passedPassed
failed_check_accepted_riskautomaticThe automatic check fails, and an accepted risk is in effect.passedPassed
failedautomatic or manualThe current value does not meet the recommended value, or an attestation that the response leaves out gives this result.failedFailed, or Passed with a Completed attestation in effect
reviewautomaticThe current value is looser than the recommended value.failedFailed
attested_completedmanualAn attestation with the value Completed (completed) is in effect.passedPassed
attested_accepted_riskmanualAn attestation with the value Accepted risk (accepted_risk) is in effect.passedPassed
not_attestedmanualNo attestation is in effect.not_attestedNot attested
attestation_not_enabledmanualNobody can attest to the control.not_attestedDescriptive
descriptiveinformation-onlyThe control is reported, not rated.descriptiveDescriptive
not_applicableanyThe control does not apply to the organization.descriptiveDescriptive
not_evaluatedanyThe setting, or another setting that decides whether the control applies, could not be read.descriptiveDescriptive

No field names the kind of control; for failed, a null current_value marks a manual control. More values can be added, so count a control with an unknown status by its rating and read an unknown rating as not Passed. The status review and the attestation state review_due are not related.

Attestation states

state says whether the attestation that the response shows is in effect.

stateMeaning
in_forceThe attestation is in effect.
review_dueThe end date has come.
setting_changedThe check fails on a value other than the one whose risk was accepted, or the accepted risk was already recorded as ended.
check_passingThe check passes, so there is no risk to accept.

When more than one reason applies, the response gives the first of check_passing, setting_changed, and review_due. From 00:00 UTC on its end date, an attestation is not in effect. The response has no end date, so state decides; an end date that was saved is the attestation activity’s review_date. Read an unknown state as not in effect.

How an attestation shows in the response

The response shows some attestations and leaves others out, so a null attestation does not prove that nobody attested.

Kind of controlAttested asstatusratingattestation
ManualNo attestationnot_attested, or attestation_not_enabled where nobody can attestnot_attestednull
ManualCompletedattested_completedpassedShown
ManualAccepted riskattested_accepted_riskpassedShown
ManualFailed (control_failed)failedfailednull: never shown
Automatic, check failedNo attestationfailed or reviewfailednull
Automatic, check failedAccepted riskfailed_check_accepted_riskpassedShown
Automatic, check failedCompletedfailed, even where the automatic check gives reviewfailednull: never shown
Automatic, check failedFailedThe status the automatic check givesfailednull: never shown
Automatic, check passedNo attestationpassed, matches_profile, or exceeds_baselinepassednull
Automatic, check passedCompletedThe status the automatic check givespassednull: never shown
Automatic, check passedAccepted riskThe status the automatic check givespassednull while the check passes on the accepted value
Automatic, check passedFailedfailedfailednull: never shown
Information-onlyAny valuedescriptivedescriptivenull: never shown
Any, while the attestation is not in effectA value that an earlier row showsAs with no attestationAs with no attestationShown, with a state other than in_force
Any, while the attestation is not in effectA value that an earlier row leaves outAs with no attestationAs with no attestationnull

Each row but the last two holds while the attestation is in effect. On an automatic control, an attestation is not in effect while the value that the check reads differs from the one that it was saved on. Every attestation that the response shows on an automatic control is an accepted risk. The Activity Feed also records attestations of the kinds that the response leaves out.

Count results

Check four things when you count controls by rating.

If you countAlso check
Passed (passed)It includes every control with an accepted risk in effect, so look for failed_check_accepted_risk and attested_accepted_risk.
Failed (failed)It includes a control attested as Failed (control_failed) and a failing automatic check with a Completed attestation in effect, which the Security posture page shows as Passed.
Descriptive (descriptive)It can hide a control that could not be read, so look for not_evaluated.
Every controlA control missing from the response is not Passed and is not named, so compare id values with those that you have seen for the organization.

Who attested, and comments

attested_by is filled only for a key that holds read:compliance_user_data together with read:compliance_org_data or that holds read:org_audit. A key with only read:compliance_user_data gets a 403. The user_id in attested_by is the same as the actor’s user_id on the attestation activity. attested_by holds only the user ID: List organization users gives the name and email address of each current member. Before you add these scopes, see Who can see who attested.

The endpoint returns no comments, even when the Security posture page shows one: every comment is null, and comments_status is not_enabled or not_permitted. So not_enabled and a null comment do not mean the attestation has no comment. comments_status says how to read a null comment, and the schema defines these values.

comments_statusMeaning
not_permittedThe API key holds neither read:compliance_user_data nor read:org_audit, so every comment and every attested_by is null.
requires_organization_keyThe API key was not created in the organization, as with a key for the parent organization, so every comment is null. Retrying does not help.
availableComments were read, so a null comment means that there is none or that it was saved moments ago.
not_enabledThis endpoint does not return comments for the organization, so every comment is null.
unavailableComments could not be read for this response; a later request might succeed, but some causes last until the customer acts.

More values can be added; read an unknown one as unavailable.

Errors

Errors use the same body as the rest of the Compliance API; this table lists the ones that this endpoint returns in its own way.

Status and error.typeWhenWhat to do
400 invalid_request_erroranthropic-version is missing or invalid, the Compliance API is not enabled for the parent organization, or there is a query parameter.Fix what error.message names.
401 authentication_errorThe key is missing, not recognized, or not a Compliance Access Key or Admin API key.Send a valid Compliance Access Key in x-api-key.
403 permission_errorThe key may not call this endpoint, usually because it lacks both read:compliance_org_data and read:org_audit.Use a key with either scope.
404 not_found_errorSee the causes listed after this table.Do not retry at once and never read it as no failed controls.
429 rate_limit_errorThe shared Compliance API rate limit, or this endpoint’s lower limit, is used up; error.message says which.Wait for retry-after; see 429 Too Many Requests.
503 overloaded_error, with error.details.error_code of posture_evaluation_failedThe result could not be produced.Wait for retry-after, then retry; if it recurs for one organization on later runs, contact Anthropic support once.
503 with no error_code, or 504 timeout_errorA temporary failure.Retry with exponential backoff.

Causes of a 404:

  • organization_id is not a UUID, names no organization, or names a deleted one.
  • organization_id names the parent organization, an organization under another parent, or one that a single-organization key does not cover.
  • The organization is not on Claude Enterprise, or Security posture is not available to it, as with a Claude Console organization.
  • The Security posture page has been turned off for the organization (see Security posture availability).
  • Security posture is available to the organization, but the endpoint does not serve it.
  • Availability could not be checked; a later request can succeed.

Every 404 has the same body, as does a path that does not exist.

Freshness and side effects

The endpoint evaluates every control when you call it, and evaluated_at is that time.

  • A change from the last few minutes might not show.
  • A result can change with no setting changed, for example when an end date comes or Anthropic changes a recommended value.
  • If Anthropic rewords a current value, an accepted risk on it is not in effect.
  • A call stores no result and ends no attestation.
  • Each request that passes the key, scope, and version checks without a query parameter records one compliance_api_accessed activity, whether it succeeds or fails; its url names the organization read, and organization_uuid is null for a key for the parent organization.

Was this page helpful?