API Reference
Every Excloud product is backed by an HTTP API. The CLI, console, and Terraform provider all sit on top of these. This page covers the contract that’s the same across every service; per-service Swagger UIs are linked at the bottom.
Base URLs
| Service | Base URL | Spec |
|---|---|---|
| Compute | https://compute.excloud.in | Swagger |
| IAM | https://iam.excloud.in | Swagger |
| DNS | https://dns.excloud.in | Swagger |
| Database | https://database.excloud.in | Swagger |
| Object Storage (control) | https://buckets.excloud.in | Swagger |
| Object Storage (S3) | https://<org-id>.buckets.excloud.in | S3 v4 signatures |
| Secrets | https://secrets.excloud.in | Swagger |
| Kubernetes | https://k8sapi.excloud.in | Swagger |
All services speak JSON over HTTPS. The S3 endpoint on object storage is the exception — it speaks the S3 protocol so existing tools (aws s3, MinIO client, boto3, rclone) work unchanged.
Authentication
Every request to a control-plane API carries a bearer token:
Authorization: Bearer <token>You can get a token three ways:
exc login— interactive flow, writes a long-lived access token to~/.exc/config. Best for laptops.- API key — create one with
exc apikey create(or in the console). Best for scripts and CI. - Service account —
exc serviceaccountcreates a non-human identity that policies can bind to. Best for production workloads and least-privilege automation.
Tokens are scoped to one org at a time. The exc login flow records the active org alongside the token; for API keys and service accounts the org is fixed at creation.
What each one can do is controlled by IAM policy. See the Policies guide and Permissions Reference.
Error format
Errors are JSON with a stable shape:
{
"error": {
"code": "compute.instance.not_found",
"message": "instance 42 not found",
"request_id": "01HE9X…"
}
}codeis a dotted identifier safe to switch on.messageis human-readable; don’t parse it.request_idis what to quote when emailing support.- HTTP status follows the usual rules:
400for client errors,401unauthenticated,403denied by policy,404not found,409conflict,429rate-limited,5xxserver-side.
Regions and zones
Excloud is single-region (Mumbai, mum) with one zone today (mum-1a, zone_id=1). Inside the region, resources live in zones. List endpoints that span zones (/compute/list, /database/list, /subnet/list) accept a zone_id query parameter; omit it to query across all zones. The API surface already takes zone_id so your code doesn’t change when more zones come online.
Async operations and --wait
Create, restart, stop, terminate, resize, and similar verbs return as soon as the request is accepted. The actual work happens asynchronously and you need to poll for terminal state.
Two patterns are supported:
- Poll yourself — call
GET /<resource>/<id>and inspect thestatusfield. Terminal states arerunning,stopped,terminated,error. Poll every few seconds. - Use
--wait— the CLI does the polling for you. The Terraform provider does the same automatically, with a 30-minute default timeout.
There’s no separate “operations” resource; the request returns the new resource ID immediately and you poll the resource itself.
Pagination
Most list endpoints return all results in one response. The exceptions:
- Serial logs (
GET /compute/:id/serial-logs) use a cursor:boot_id,offset,direction(older/newer), andlimit(default 200, max 1000). - Bucket object listing follows S3 semantics (
max-keys,marker/continuation-token).
If you hit a list endpoint where pagination would matter and there’s no cursor today, — we’ll add it.
Versioning
APIs are additive-only within a major version. Breaking changes ship behind a new path prefix (e.g. /v2/…). Today only Object Storage uses an explicit /v1/ prefix because of the S3-compatible surface; the rest are at the root and are considered v1 implicitly.
Field additions, new optional query parameters, and new endpoints are not breaking. Removing a field or changing its type is.
Rate limiting
There is no published per-account rate limit today. We reserve the right to throttle abusive clients with 429 Too Many Requests. Retry with exponential backoff; the response includes a Retry-After header when set.
Webhooks
Two webhook receivers exist today, both consumed internally:
- IAM accepts WhatsApp delivery webhooks (
/webhook/whatsapp). - Billing accepts Razorpay payment webhooks (
/webhooks/razorpay).
Outbound webhooks (Excloud → your endpoint) are not exposed yet.
Per-service docs
| Service | Concept docs | Swagger |
|---|---|---|
| Compute | Concept guide | compute.excloud.in/docs |
| Object Storage | Concept guide | buckets.excloud.in/docs |
| Secrets | Concept guide | secrets.excloud.in/docs |
| Kubernetes | Concept guide | k8sapi.excloud.in/docs |
| DNS | Concept guide | dns.excloud.in/docs |
| Database | Concept guide | database.excloud.in/docs |
| IAM | Policies, Permissions | iam.excloud.in/docs |