Containers
Create with {"catalogId":"node","size":"medium"}. All plans offer lite, small, medium, large, and xl; Lite is the default. Size also participates in creation idempotency. Read compute allowances and deadlines before launching.
All browser sessions and API keys for an account share the same containers, concurrency, monthly compute-unit hours, and monthly start allowance. Base URL: https://api.mainbrella.com.
| Request | Behavior |
|---|---|
GET /containers | Returns containers, active access, plan, limits, usage, and the deployed image catalog. Reading status does not renew idle time. |
POST /containers | Reserves a start and launches a container. An omitted body selects the default Node image. Optional JSON selects catalogId or an owned, ready imageId. |
DELETE /containers?id=…&createdAt=… | Stops only the selected container generation. Stopping does not refund a start. |
Create safely
Send a unique Idempotency-Key header for each new launch. Repeating the same body and key resolves to the same reservation for 24 hours. Preserve the key until the response is reconciled.
POST /containers
Authorization: Bearer mb_<your-key>
Content-Type: application/json
Idempotency-Key: <unique-operation-key>
{"catalogId":"node"}
With an idempotency key, the response includes creation. Use its containerId and createdAt, matched to a running entry in containers, rather than selecting the first container in the list. A reservation can still be starting; repeat the same POST to reconcile it.
Keep the generation
A slot ID can be reused after a stop. The exact returned createdAt identifies that instance. Execution and file requests require it; supply it when stopping or issuing SSH access as well. URL-encode query values with your language's URL utilities.
Lifecycle
Containers end at their plan's hard deadline, the paid period recognized at creation, or their idle timeout. Renewals and upgrades do not extend existing sessions. Commands and terminal activity renew idle time only. A stopped container loses its files.
Check allowance before launching. Failed starts count toward monthly usage; requests rejected at concurrency capacity do not.
Protected application previews
Preview ingress is implemented locally and awaits isolated-domain configuration and live qualification. Check GET /capabilities; use it only when previews.supported is true. The dashboard then shows a Preview control beside each container. Start your HTTP server first, enter its port, and create a link. The dashboard shows expiration and lets you revoke access.
POST /containers/previews?id=<id>&createdAt=<generation>
Authorization: Bearer mb_<your-key>
Content-Type: application/json
{"port":3000,"ttlSeconds":900}
The response contains {id, port, createdAt, expiresAt, url}. The HTTPS URL gives anyone who has it access to the selected port. It is returned once; share deliberately and keep it out of logs and analytics. expiresAt is Unix milliseconds. Links last 60–3600 seconds, default to 15 minutes, and end no later than the container deadline. Ports 1024–65535 are eligible; eight grants can be active per generation.
List active metadata with GET /containers/previews?id=…&createdAt=…; URLs cannot be recovered after reload. Revoke with DELETE /containers/previews?id=…&createdAt=…&previewId=…. Revocation closes active connections. Stop, expiry, or generation replacement invalidates access. Listing and revocation remain available when new issuance is disabled.
Creating a link is not idempotent. After a lost response, list and revoke the unwanted grant before creating another. A preview_reconciliation_required error includes previewId; retry DELETE with that ID and the same generation. Requests never start or restart a container. Cookies and Authorization are stripped; cookie sessions, external Host semantics and absolute redirect rewriting are unsupported. See the full contract and local JavaScript / Python helpers.