Appearance
Orders beta
Order products like in the Console's builder ("Buy").
| Method | Path | Notes |
|---|---|---|
| GET | /teams/{team}/orders | ?status=, ?per_page= (max 100) |
| POST | /teams/{team}/orders | full scope of every item's family (or user); Idempotency-Key required |
| GET | /teams/{team}/orders/{order} |
{team} must be one of your teams (owner or member), otherwise 404. A team managed by an app (see Apps acting for users) can be read here, but orders for it go through that app only (403, error: team_managed_by_app).
Placing an order
http
POST /v1/teams/{team}/orders
Idempotency-Key: 7b0c4c2e-…
Content-Type: application/json
{
"items": [{
"family": "server",
"product_id": "01JC…",
"attributes": {"location_id": "bon1", "operating_system_id": "01JC…", "vlan_id": "01JC…"}
}],
"tos_accepted": true,
"withdrawal_waiver": true,
"coupon_code": "SPRING"
}bash
curl -X POST "https://console.anikeen.com/api/v1/teams/$TEAM/orders" \
-H "Authorization: Bearer $ANIKEEN_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"items":[{"family":"server","product_id":"01JC…","attributes":{"location_id":"bon1","operating_system_id":"01JC…","vlan_id":"01JC…"}}],"tos_accepted":true}'php
$order = $console->orders($team)->create([
['family' => 'server', 'product_id' => $planId, 'attributes' => [
'location_id' => 'bon1',
'operating_system_id' => $imageId,
'vlan_id' => $vlanId,
]],
], ['tos_accepted' => true]);Body
| Field | |
|---|---|
items | 1–10 items: family and product_id from the catalog, attributes per family (see Order attributes) |
tos_accepted | required, true: you accept the terms of service |
withdrawal_waiver | optional: start right away and waive the right of withdrawal (consumers; ignored for business customers with a verified VAT ID). Anikeen ID asks for it again when the order is confirmed |
coupon_code | optional: a coupon like in the builder (must fit every product and have uses left). Not for reseller teams (422). A coupon that names coupon-only products makes those orderable |
return_url | optional, app tokens only (any other token: 422, the field is prohibited): where your user lands after the checkout - see below. Absolute URL, max. 2000 characters, https (plain http only for localhost, 127.0.0.1, ::1), no user info |
Names that must be unique (domain, zone, hosting, objectStorage) must also differ between the items of one order (case-insensitive).
Who orders decides what happens
| Who | What happens | Response |
|---|---|---|
| Team owner | The order is saved and an Anikeen ID checkout is opened. Nothing is charged before you confirm. | 201, status: "open", a checkout_url |
| Member, and the owner allows members to order (team setting "Members may buy") | Charged right away to the owner's default payment method, without a confirmation (the owner gets an e-mail). | 201, status: "completed", checkout_url: null |
| Member without that setting | Nothing is ordered. | 403, error: owner_only |
Confirming the checkout (team owner)
- Open the
checkout_urlin a browser, signed in to Anikeen ID as the owner. Anikeen ID shows the price, billing address and payment method. - Confirm before
expires_at. The order is concluded when you confirm. - Poll
GET /teams/{team}/orders/{order}: for an open order it asks Anikeen ID for the state, turnscompletedonce confirmed (cancelled/expiredotherwise) and lists every built product.
Back to your app (return_url)
Without return_url, the owner lands on the Console's order page after the checkout. An app (app tokens only) can send its own page instead:
json
{
"items": [{"family": "container", "product_id": "01JC…", "attributes": {…}}],
"tos_accepted": true,
"return_url": "https://app.example/ordered?from=console"
}Anikeen ID only returns to the Console's own address, so the checkout comes back to a signed Console link (no Console login needed). It asks Anikeen ID for the order's state, starts the setup if the order was confirmed, and redirects to your URL with two query parameters added (other parameters and a fragment are kept):
text
https://app.example/ordered?from=console&console_order=01JE…&status=completed| Parameter | |
|---|---|
console_order | the order's id |
status | its status at that moment: completed, open (Anikeen ID has not settled it yet), cancelled, expired, failed |
Do not trust the parameters
Read the order (GET /teams/{team}/orders/{console_order}) and wait for completed - or the order.completed webhook. The order completes through Anikeen ID whether or not the user ever comes back.
A direct purchase (member) has no checkout and ignores return_url.
Reading an order
http
GET /v1/teams/{team}/orders/{order}json
{"data": {
"id": "01JE…", "team_id": "01JA…", "status": "open", "mode": "session", "source": "api",
"checkout_url": "https://id.anikeen.com/checkout/sessions/…",
"expires_at": "2026-11-10T12:00:00+00:00",
"error": null,
"items": [{
"id": "01JE…", "family": "server", "product_id": "01JC…", "product_name": "VPS S",
"unit": "hour", "list_price": 0.02, "price": 0.02,
"status": "pending", "product": null, "provisioned_at": null
}],
"created_at": "…", "completed_at": null
}}| Field | Values |
|---|---|
status | pending → open → completed, or cancelled, expired, failed |
mode | session (confirmed on Anikeen ID) or direct (a member's purchase) |
source | api or console |
checkout_url | shown only to the user who placed the order, while it is open |
items[].status | pending → provisioned, or failed (not built, refunded) |
items[].product | once provisioned: {type, id}, e.g. {"type": "server", "id": "01JD…"} - the id works with /servers/{server} etc. |
The products are set up in the background after the order completed.
The order list holds the team's orders placed in the Console too (source: console), but not the takeovers of transferred products.
Errors
Besides 422 (keys like items.0.attributes.location_id; nothing ordered):
| Status | error | |
|---|---|---|
403 | owner_only | a member, and the owner does not allow members to order |
403 | missing_scope | a token with console-* scopes lacks the full scope of an item's family (scope names it) |
403 | team_managed_by_app | the team is managed by an app: orders go through that app |
409 | owner_sign_in_required | member purchase: the owner's Anikeen ID login expired - the owner must sign in to the Console once |
409 | order_refused | e.g. the owner has no default billing address or payment method, or the reseller team may not order |
402 | order_failed | member purchase: the charge failed (order holds the failed order; every subscription was revoked) |
502 | checkout_unavailable | the checkout could not be opened on Anikeen ID (order holds the failed order); try again with a new key |
429 | rate_limited | more than 10 orders per minute and team (Retry-After) |
See also Idempotency and Rate limits.