Build your own control surface
A prepared API contract for a future control plane: resources, scopes, limits and event handling.
Content revised · English
- Contract state
- Prepared, not served
- Read limit
- 60 / minute
- Write limit
- 20 / minute
- Version retirement
- 6 months notice
Proposed burst allowance ×2.
Proposed burst allowance ×2.
Proposed deprecation window.
Keep these in view.
- There is no live API origin or functioning SDK behind this page.
- Separate resource reads from changes with least-privilege scopes.
- Use idempotent requests and signed events before automating billing or delivery.
Start with a small, stable resource model
The proposed version-one contract separates catalogue resources from account resources. Locations and plans support configuration. Services represent accepted configurations and fulfilment state. Billing contains invoices and payment state. Tickets support a traceable support conversation. The website implements its own forms and workspace; the examples below are a design contract, not routes to a public API.
Credentials belong to a scope
The prepared authentication model uses a Bearer token in the Authorization header. Read-only catalogue or service scopes should not be able to create, rebuild or cancel a service. Write scopes need a distinct decision and revocation path. Keep credentials in a private server environment and never embed a secret token in a page or browser bundle.
GET /v1/services
Authorization: Bearer <private-token>
Accept: application/json
# Proposed scope: services:readFive illustrative operations
Use a stable identifier for each resource and a request ID for support. Mutating calls should take an idempotency key so a retry can be reconciled instead of creating another order.
POST /v1/services
Idempotency-Key: <one-key-per-request>
{
"plan_id": "umbra-1",
"location": "iceland",
"billing_cycle": "monthly",
"image": "Ubuntu"
}| Operation | Illustrative request | Required scope | Result |
|---|---|---|---|
| List services | GET /v1/services | services:read | Items and cursor |
| Read locations | GET /v1/locations | catalogue:read | Regional metadata |
| Read plans | GET /v1/plans | catalogue:read | Capacity, cycles and compatibility |
| Create a service request | POST /v1/services | services:write | Accepted request and current state |
| Read an invoice | GET /v1/billing/invoices/{id} | billing:read | Total and payment state |
Limits and a useful error envelope
The proposed account-level rate limits are 60 reads per minute and 20 writes per minute, with a burst allowance of twice those values. A rejected request returns HTTP 429 with Retry-After; automation should wait as instructed and apply backoff. Errors should include a stable code, a human-readable message and a request_id, with sensitive details removed.
{
"error": {
"code": "unsupported_location",
"message": "This plan is not listed in that region.",
"request_id": "req_example"
}
}Events, signatures and safe retries
The prepared webhook model covers invoice payment, service readiness, suspension and ticket updates. Delivery should have an event ID and timestamp, with an HMAC-SHA256 signature checked over the original request body using a private signing secret. Reject stale or invalid signatures, deduplicate event IDs and acknowledge only after the event is durably accepted. Consumers must tolerate out-of-order and repeated delivery.
Version the contract before changing it
The proposed API path includes its major version. Additive changes should preserve existing clients; incompatible changes need a new version and a six-month retirement notice for the old one. Availability, SDKs and a production API host must be published only after integration and security review.
The implemented payment boundary
The account application has fixed-address payment requests and expiring server USD quotes. Transaction observation is a trusted server-only integration; there is no public confirmation endpoint, connected blockchain monitor or provisioning worker. Browser polling reads the signed-in customer’s existing payment state and cannot attest to a transaction. The illustrative public API and webhook contract above remain future design work.
- Protect rate and observation logic on the server.
- Associate reused receiving destinations with a verified transaction and explicit order reference.
- Keep paid and provisioned separate; a verified transaction must not create fictitious hardware.
A final practical check.
- Separate read-only and write tokens.
- Keep a request ID, without logging secrets or full credentials.
- Treat a network timeout as an uncertain result; reconcile before retrying.
- Verify event signatures before updating an order.
Questions, answered.
Can I use these examples against ombrahost.com today?
No. They describe a prepared contract. This project has no live API origin, token issuing service or webhook sender.
Does the website include a working Ombra CLI or SDK?
No CLI or SDK is claimed. The interface and account workflows are implemented separately from this future API design.