Response Envelope
Every response from the Asterwise API uses one of two envelope shapes — a success envelope or an error envelope. Both are stable across all 115 endpoints and across versions. Build your client against these shapes and you can add or remove endpoints without touching response-handling code.
Success envelope
When a request succeeds, the response body has three fields:
{
"success": true,
"message": "success",
"data": { /* endpoint-specific payload */ }
}
| Field | Type | Always present | Description |
|---|---|---|---|
success | boolean | Yes | Always true on success responses. Pair with the HTTP status code (2xx) to confirm. |
message | string | Yes | Human-readable status string. Typically "success". Not intended for end users — use HTTP status and success for branching. |
data | object | Yes | The endpoint's actual payload. Schema varies by endpoint; see the per-endpoint reference page for shape. |
Error envelope
When a request fails, the response body has eight fields:
{
"success": false,
"error": "api_key_missing",
"message": "API key is missing. Include it in the Authorization header as 'Bearer YOUR_KEY'.",
"details": [],
"retry_after": null,
"doc_url": "https://docs.asterwise.com/reference/errors/api_key_missing",
"request_id": "72e02ee1-56ea-4e90-93a6-73c866ed7498",
"timestamp": "2026-05-25T18:04:59Z"
}
| Field | Type | Always present | Description |
|---|---|---|---|
success | boolean | Yes | Always false on error responses. |
error | string | Yes | Stable snake_case identifier for the failure. Branch on this — not on the HTTP status code or message text. See the errors reference for every possible value. |
message | string | Yes | Human-readable description. Safe to surface in UIs. Always under 200 characters. |
details | array | Yes | Structured details about the failure. Empty array [] if no detail is meaningful. For validation_error, contains per-field violations. |
retry_after | integer or null | Yes | Seconds to wait before retrying. Non-null only for rate-limit codes (see rate limits). When non-null, the HTTP Retry-After header carries the same integer. |
doc_url | string | Yes | Permalink to the error reference page. Useful for surfacing in dashboards and logs so engineers can look up the failure. |
request_id | string or null | Yes | UUID assigned by Asterwise. Identical to the X-Request-Id response header. Include this when contacting support so we can trace the exact request. |
timestamp | string or null | Yes | ISO 8601 UTC timestamp of when the error was generated server-side. |
Branching on responses
Always branch on success (or the HTTP status code), then on error:
- Python
- TypeScript
- curl
import requests
response = requests.get(
"https://api.asterwise.com/v1/astro/ayanamsha",
headers={"Authorization": "Bearer YOUR_KEY"},
)
body = response.json()
if body["success"]:
ayanamsha = body["data"]["ayanamsha"]["lahiri"]["value_decimal"]
else:
if body["error"] == "ip_rate_limit_exceeded":
# Standard HTTP retry middleware will already honor Retry-After
...
elif body["error"] == "api_key_revoked":
# Refresh credentials and retry
...
else:
print(f"Error {body['error']}: {body['message']}")
print(f"Request ID: {body['request_id']}")
print(f"Docs: {body['doc_url']}")
import type { ErrorCode } from "asterwise/types";
interface SuccessResponse<T> {
success: true;
message: string;
data: T;
}
interface ErrorResponse {
success: false;
error: ErrorCode;
message: string;
details: unknown[];
retry_after: number | null;
doc_url: string;
request_id: string | null;
timestamp: string | null;
}
type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
const response = await fetch("https://api.asterwise.com/v1/astro/ayanamsha", {
headers: { Authorization: "Bearer YOUR_KEY" },
});
const body: ApiResponse<AyanamshaData> = await response.json();
if (body.success) {
const lahiri = body.data.ayanamsha.lahiri.value_decimal;
} else {
if (body.error === "ip_rate_limit_exceeded") {
// Type narrows; retry_after is number for rate-limit codes
} else if (body.error === "api_key_revoked") {
// ...
}
}
The ErrorCode Literal type from asterwise/types narrows automatically — TypeScript knows every valid wire value. See the TypeScript SDK for installation.
curl -sS -H "Authorization: Bearer YOUR_KEY" \
https://api.asterwise.com/v1/astro/ayanamsha | jq '.success, .error // .data | keys'
OAuth endpoints — exception
A single family of endpoints uses a different envelope: any path under /v1/oauth/*. These follow the RFC 6749 OAuth 2.0 error format because OAuth clients expect it. The shape is:
{
"error": "invalid_request",
"error_description": "Missing required parameter: code_verifier"
}
This is the only place in the API where the canonical 8-field envelope does not apply. Outside /v1/oauth/*, every endpoint uses the canonical error envelope.
Stability promise
The success envelope and error envelope shapes are part of our versioning contract. We will not remove fields or change types within v1. We may add new fields — clients should ignore unknown fields and not break on them.