Ownership Denied
ownership_denied403
The key is valid, but the resource you're trying to access belongs to another account.
What this means
Your API key is authenticated and authorized for this endpoint family, but the specific resource ID in the request URL (a key ID, account ID, subscription ID, etc.) belongs to a different account. We refuse the request to prevent one customer from reading or modifying another customer's data — even by accident, even with the resource ID guessed correctly.
When you'll see this
- A frontend used the wrong account context when constructing the API call (e.g. impersonation gone wrong, stale session state).
- A key from account A tried to modify a resource (key, subscription, invoice) that belongs to account B.
- A copy-pasted resource ID from another environment (staging, another tenant) was used in a production call.
- A bug in your own access-control layer let one user request data scoped to another user.
Learn more about how this works
Asterwise enforces ownership at the resource boundary, not just at the key boundary. Even a fully-scoped key can only operate on resources owned by its parent account. This is intentional: it means a key leak only exposes that account's data, not the entire platform.
The most common gotcha: this error fires for "not found" cases too. If you request a resource ID that doesn't exist anywhere in our system, you'll get this 403 rather than a 404 — disclosing whether a resource exists at all would leak account information to anyone willing to scan IDs. From your code's perspective, treat ownership_denied as "this resource is not yours, and we won't tell you why."
Example response
{
"success": false,
"error": "ownership_denied",
"message": "You do not have permission to access this resource.",
"details": [],
"retry_after": null,
"doc_url": "https://docs.asterwise.com/reference/errors/ownership_denied",
"request_id": "req_01HXYZABCDEFGH",
"timestamp": "2026-05-25T12:34:56Z"
}
- Confirm the resource ID in the failing request belongs to the account that owns your API key.
- If you have access to multiple accounts (consulting, agency, multi-tenant work), verify your client code is using the correct key for the resource's account.
- If you're sure the resource should be yours and you're still seeing this, email [email protected] with the
request_idand the resource ID — we can confirm ownership without exposing other accounts.
This is not retriable. Treat it as a hard authorization failure and route accordingly.
Python:
Production handler
- Python
- TypeScript
import httpx
class AsterwiseOwnershipError(Exception):
"""Resource exists for another account or doesn't exist at all."""
def call_asterwise(url, headers):
response = httpx.get(url, headers=headers, timeout=30)
if response.status_code == 403:
body = response.json()
if body.get("error") == "ownership_denied":
raise AsterwiseOwnershipError(
f"Resource at {url} is not owned by this account. "
f"Check resource ID and key alignment. "
f"request_id={body.get('request_id')}"
)
response.raise_for_status()
return response.json()
class AsterwiseOwnershipError extends Error {}
async function callAsterwise(url: string, headers: HeadersInit) {
const response = await fetch(url, { headers });
if (response.status === 403) {
const body = await response.json();
if (body.error === "ownership_denied") {
throw new AsterwiseOwnershipError(
`Resource at ${url} is not owned by this account. ` +
`Check resource ID and key alignment. ` +
`request_id=${body.request_id}`
);
}
}
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
Avoid this error by
- Always pair API keys with their owning account in your secrets manager —
ASTERWISE_KEYis ambiguous when you handle multiple accounts;ASTERWISE_KEY_PROD_TENANT_Ais not. - Validate resource IDs against the current session's account before sending them to Asterwise. Catching this on your side gives the user a clearer error than a 403 from us.
- Never hardcode resource IDs across environments. A staging key ID has no business in a production deploy.
- If you're building a multi-tenant product on top of Asterwise, never expose raw resource IDs to end users. Map them to your own opaque tokens.