> For the complete documentation index, see [llms.txt](https://docs.omnata.com/omnata-product-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.omnata.com/omnata-product-documentation/omnata-sync-for-snowflake/apps/claude.md).

# Anthropic Admin APIs

The Omnata Plugin for Anthropic Admin APIs pulls administrative, compliance, and usage data from Anthropic into Snowflake. It uses two Anthropic API surfaces:

* The **Admin API** (`/v1/organizations/*`) — workspaces, console users, API keys, invites, rate limits, and Anthropic Console usage and cost reporting (including a per-actor Claude Code usage report).
* The **Compliance API** (`/v1/compliance/*`) — Anthropic's enterprise compliance feed: activities, directory data (orgs / users / roles / groups), claude.ai projects, and per-user chat metadata.

You can connect with either key, or both. Stream availability depends on which key(s) you provide on the connection. This plugin support inbound syncs only.&#x20;

### Prerequisites

#### Anthropic

You need one or both of the following keys from **platform.claude.com**:

**Admin API Key** (`sk-ant-admin01-...`)

* Created by an Anthropic Console organization owner under **Settings → Admin Keys**.
* Required scope: the Admin API key is itself the scope — it grants the Admin API endpoints listed above to its holder.

**Compliance Access Key** (`sk-ant-api01-...`)

* Issued by Anthropic as part of the **Compliance API** programme. Compliance API access is an **Enterprise Plan** feature and must be enabled on your Anthropic organization — contact your Anthropic account team if you don't yet have access.
* See Anthropic's [Compliance API access provisioning documentation](https://platform.claude.com/docs/en/manage-claude/compliance-api-access) for the request flow.

{% hint style="info" %}
Each key unlocks a different set of streams in this plugin. Provide both keys if you want full coverage across the Admin API and Compliance API surfaces.
{% endhint %}

### Authentication

The plugin has one connection method, **API Keys**, with two optional fields. At least one must be populated.

<table><thead><tr><th>Field</th><th>Notes</th><th data-hidden>Required</th></tr></thead><tbody><tr><td>Compliance Access Key</td><td>Format <code>sk-ant-api01-...</code>. Stored as a secret in Snowflake. Unlocks the Compliance API streams (see below).</td><td>One of the two required</td></tr><tr><td>Admin API Key</td><td>Format <code>sk-ant-admin01-...</code>. Stored as a secret in Snowflake. Unlocks the Admin API streams (see below).</td><td>One of the two required</td></tr></tbody></table>

### Inbound Syncs

The streams listed in the configuration UI are gated by which key you supplied. If you provide only one key, only that key's streams appear. If you provide both, all streams appear.

#### Streams unlocked by the Compliance Access Key

<table><thead><tr><th width="188.52734375">Stream</th><th>Sync strategies</th><th width="120.9296875">Primary key</th><th>Depends on</th></tr></thead><tbody><tr><td><code>activities</code></td><td>Full Refresh, Incremental</td><td><code>id</code></td><td>—</td></tr><tr><td><code>organizations</code></td><td>Full Refresh</td><td><code>uuid</code></td><td>—</td></tr><tr><td><code>organization_users</code></td><td>Full Refresh</td><td><code>id</code></td><td><code>organizations</code></td></tr><tr><td><code>organization_roles</code></td><td>Full Refresh</td><td><code>id</code></td><td><code>organizations</code></td></tr><tr><td><code>groups</code></td><td>Full Refresh</td><td><code>id</code></td><td>—</td></tr><tr><td><code>group_members</code></td><td>Full Refresh</td><td><code>group_id</code> + <code>user_id</code></td><td><code>groups</code></td></tr><tr><td><code>projects</code></td><td>Full Refresh</td><td><code>id</code></td><td>—</td></tr><tr><td><code>project_attachments</code></td><td>Full Refresh</td><td><code>project_id</code> + <code>id</code></td><td><code>projects</code></td></tr><tr><td><code>user_chats</code></td><td>Full Refresh</td><td><code>id</code></td><td><code>organization_users</code></td></tr></tbody></table>

#### Streams unlocked by the Admin API Key

Omnata fetches from the four APIs under the umbrella of Admin:

* Admin API
* Usage & Cost
* Rate Limits
* Claude Code Analytics

The 'report' streams function like a reporting cube and you need to configure the granularity of reporting you want to extract, see [Usage report configuration](#usage-report-configuration).

| Stream                     | Sync strategies           | Primary key         |
| -------------------------- | ------------------------- | ------------------- |
| `admin_users`              | Full Refresh              | `id`                |
| `workspaces`               | Full Refresh              | `id`                |
| `api_keys`                 | Full Refresh              | `id`                |
| `invites`                  | Full Refresh              | `id`                |
| `rate_limits`              | Full Refresh              | `group_type`        |
| `usage_report`             | Full Refresh, Incremental | `id`                |
| `cost_report`              | Full Refresh, Incremental | `id`                |
| `claude_code_usage_report` | Full Refresh, Incremental | `date` + `actor_id` |

#### How dependent streams work

Streams marked as depending on another (e.g. `organization_users` depends on `organizations`) are populated as a by-product of the parent's iteration. The sync engine schedules the parent first and the child receives one batch of rows per parent record. This means a Full Refresh of, say, `group_members` is implicitly scoped to the groups returned by `groups` in the same sync run.

#### Usage report configuration

The Admin API supports configurable bucketing and grouping for usage reports. You may need to configure multiple syncs to extract reports of different granularities. When the Admin API Key is set, the inbound sync configuration form exposes two parameters that apply to the `usage_report` stream:

| Parameter                  | Default                                      | Options                                                                                                                      | Notes                                                                                                                         |
| -------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Usage report — granularity | Daily (`1d`)                                 | Daily (`1d`), Hourly (`1h`), Minute (`1m`)                                                                                   | Time bucket size. Daily is recommended; hourly produces 24× the row volume and minute produces 1,440× the row volume.         |
| Usage report — grouping    | `api_key_id,workspace_id,model,service_tier` | `api_key_id`, `workspace_id`, `model`, `service_tier`, `context_window`, `inference_geo`, `account_id`, `service_account_id` | Multi-select. Each additional grouping multiplies the row count. An empty grouping returns one aggregate row per time bucket. |

{% hint style="warning" %}
Combining minute-level granularity with several grouping dimensions can rapidly produce millions of rows per day. Start with the defaults and add granularity only where you need it.
{% endhint %}

The `cost_report` stream uses the same time bucketing as `usage_report` (it shares the granularity setting).&#x20;

### Functions

The plugin exposes two consumer-callable UDTFs under `<plugin_app>.UDFS.*`.

#### `CLAUDE_API_REQUEST`

Generic Claude API caller. Uses whichever key is populated on the connection (Compliance Access Key is preferred, then Admin API Key). The path must begin with `/`.

```sql
SELECT STATUS_CODE, RESPONSE
FROM TABLE(
  PLUGIN_CLAUDE_APP_<user>.UDFS.CLAUDE_API_REQUEST(
    'my_claude_connection',
    'GET',
    '/v1/compliance/activities',
    OBJECT_CONSTRUCT('limit', 10),
    NULL
  )
);
```

Grant this UDTF to roles that need broad access to Claude API endpoints reachable by the connection's keys.

#### `CLAUDE_COMPLIANCE_API_REQUEST`

Locked-down sibling. Two enforcement layers, in addition to the key checks above:

* Reads **only** the Compliance Access Key from the connection. The Admin API Key is ignored even if populated.
* Rejects any PATH that does not start with `/v1/compliance/`.

Grant this UDTF (and not the generic one) to roles that must not be able to reach the Admin API or other Claude endpoints.

```sql
SELECT STATUS_CODE, RESPONSE
FROM TABLE(
  PLUGIN_CLAUDE_APP_<user>.UDFS.CLAUDE_COMPLIANCE_API_REQUEST(
    'my_claude_connection',
    'GET',
    '/v1/compliance/activities',
    OBJECT_CONSTRUCT('limit', 10),
    NULL
  )
);
```

### Troubleshooting

**"Connection failed (401)" on the connect step**

* For a Compliance Access Key, confirm the key starts with `sk-ant-api01-` and that Compliance API access has been enabled on your Anthropic organization.
* For an Admin API Key, confirm the key starts with `sk-ant-admin01-` and was created under the Anthropic Console for your organization.

**"Connection failed (404)" or empty Activity Feed**

The Compliance Activity Feed (`/v1/compliance/activities`) is only populated for organizations with Compliance API enablement. A 404 on the smoke test usually means the key is valid but the org is not entitled to the Compliance API. Pursue Compliance enablement with your Anthropic account team, or remove the Compliance Access Key and operate the plugin with the Admin API Key only.

**No streams visible after saving the connection**

The stream list is gated on which key is populated. If you provided only an Admin API Key, you will see the eight Admin API streams but not the Compliance streams (and vice versa). Add the second key to the connection if you want both sets to appear.

**Usage report has unexpectedly large row counts**

The `usage_report` row count is the product of (time buckets × grouping dimensions). Switching from daily to hourly multiplies the row count by 24; adding `context_window` or `inference_geo` to the grouping can substantially increase the cardinality further. Start at the defaults and add detail only as needed.

***

Last updated


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.omnata.com/omnata-product-documentation/omnata-sync-for-snowflake/apps/claude.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
