> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Share advertisers with another organization

> Invite another organization to exact advertisers, accept or reject an invitation, revoke a grant, and read grants with save_advertiser_grant, search and get.

An advertiser grant lets the organization that owns an advertiser give another
organization reviewed access to specific advertisers. A grant names every
advertiser ID and every capability, the invited organization must accept it, and
it always has an expiry date.

The owner keeps ownership and the existing advertiser and campaign IDs. A grant
does not expose account IDs, members, billing, unrelated or future advertisers,
or private advertiser configuration. A name, an email domain, a CRM association,
a signup history, a provider, an external Business Manager membership or a
Partner status never creates authority.

## Who can use grants

Grants are in limited beta. An organization can use them when all of these hold:

* it is an eligible organization (a standalone or parent account);
* Apostra has given it an active, time-limited beta entitlement; and
* Apostra has switched grants on for its cohort.

When an organization does not meet them, `save_advertiser_grant` is left out of
`tools/list` and a call is refused with `ACCESS_DENIED`. Being named in a grant
does not bypass these checks. Ask your Apostra contact to enroll the
organization.

Every grant change needs a person signed in directly as an administrator of the
organization. A service token, a user API key, an advertiser-scoped credential,
an impersonated session or an inherited child-account session cannot invite,
accept, reject or revoke, and cannot list or read grants either. Run the call in
the organization's own account: from a child account the call is refused with
"Open the Organization account before changing advertiser grants."

A buyer agent gains nothing from a grant. It reaches only the advertisers its own
organization owns, so a grant does not let it list or read a delegated advertiser
or its campaigns. See [Buyer agents](https://docs.apostra.com/v3/buyer-agents.md#what-a-grant-allows).

## Invite an organization

Use `save_advertiser_grant` with `action: "invite"`:

```json theme={null}
{
  "action": "invite",
  "grantee": { "organizationRef": "9f24ad79-d930-40b0-81a1-7c56be518f51" },
  "advertisers": [{ "advertiserId": "12345" }],
  "capabilities": ["advertiser.read", "campaign.read", "campaign.manage"],
  "purpose": "Operate the reviewed Q4 campaign portfolio",
  "expiresAt": "2026-11-30T23:59:59Z"
}
```

| Field | Rule |
| - | - |
| `grantee.organizationRef` | The exact organization reference (a UUID) the invited organization gives you. A display name or domain cannot stand in for it. |
| `advertisers` | 1 to 100 distinct advertiser IDs the inviting organization owns. A grant never covers an advertiser created later. |
| `capabilities` | Distinct values from `advertiser.read`, `campaign.read` and `campaign.manage`. Every grant must include `advertiser.read`, and `campaign.manage` also needs `campaign.read`. Campaign management can be granted only while the owner still holds that authority directly. |
| `purpose` | Why the grant exists, 1 to 1,000 characters. |
| `expiresAt` | A future date and time no more than 365 days away. |

The inviting and invited organizations must be different. An advertiser the
inviter does not own, a system advertiser, or an expiry outside the window is
refused with `VALIDATION_ERROR` or `ACCESS_DENIED`. While a pending or active
grant exists for the same two organizations and advertiser, reject, revoke or
let it expire before you invite again; an overlapping invitation is refused with
`CONFLICT`.

The invited organization's administrator gives you its reference. The reference
also appears as `grantor.organizationRef` or `grantee.organizationRef` on every
grant that organization is part of. If the other administrator cannot find it,
ask through `save_ask`.

> [!WARNING]
>
> A grant records the reviewed campaign capabilities and the authorization
> boundary around them. Campaign read and manage grants do not yet extend the
> buyer campaign tools to the invited organization. Those tools stay scoped to
> the account that owns the advertiser until delegated campaign access is
> released.

## Accept, reject or revoke

The invited organization accepts or rejects an invitation. Only that
organization can record either answer.

```json theme={null}
{
  "action": "accept",
  "grantRef": "3b0f6c5e-5f6a-4a43-9c5e-0d3c7e0a9a21",
  "reason": "Reviewed the advertiser and capabilities"
}
```

Send `action: "reject"` to decline. The inviting organization ends a pending or
active grant at once with `action: "revoke"` and a `reason`. `accept`, `reject`
and `revoke` take only `grantRef` and `reason`; they cannot change the parties,
advertisers, capabilities, expiry or purpose.

A grant is `invited`, `active`, `rejected`, `revoked` or `expired`. Accepting,
rejecting, revoking and an observed expiry each add an event to the grant's
history; earlier events are never rewritten. A revoked or expired grant stops
working immediately, and a cached grant is never evidence of current authority:
every delegated operation checks the active, accepted grant for the exact
advertiser and capability again. Removing the beta entitlement or the cohort
exposure from either organization also stops access. It does not delete the grant
or its history.

## Read grants

Call `search` with `kind: "advertiser_grant"` in a buyer or seller account. Narrow
it with `query` or with `filter.grantStatus`, one or more of `invited`,
`active`, `expired`, `rejected` and `revoked`.

Each result holds `grantRef`, `status`, `grantor`, `grantee`, `advertiserCount`,
`capabilities`, `purposePreview` and `expiresAt`. A page holds at most 25 grants,
whatever `limit` you send. When more follow, the page is truncated: it returns
`truncated: true`, `totalLowerBound` and a `nextCursor` to pass back. Only an
untruncated first page returns the exact `total`.

Call `get` with `kind: "advertiser_grant"` and `id` set to the `grantRef` for the
whole grant: the exact advertisers, and the `events` history with each event's
`type`, `actor`, `reason` and `observedAt`. Names, purposes and reasons are
customer-written text, so Apostra wraps them as untrusted output.

## Errors

| Code | When |
| - | - |
| `VALIDATION_ERROR` | The advertiser is not owned by the inviting organization, the capability combination is invalid, or the expiry is outside the window. |
| `ACCESS_DENIED` | The caller is not a direct human administrator, is the wrong party for the change, or the organization is not enrolled. |
| `NOT_FOUND` | The organization, grant or advertiser is not visible to the caller. |
| `CONFLICT` | The grant's state, the advertiser's ownership or the owner's campaign authority changed, or an overlapping grant exists. |

See [Errors](https://docs.apostra.com/v3/errors.md) for how V3 reports them.

## Related

* [Run Apostra for several client accounts](https://docs.apostra.com/v3/several-client-accounts.md) compares
  grants with child accounts and buyer agents.
* [Account access](https://docs.apostra.com/v3/account-access.md) explains how a call names its account.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.