API Introduction
Everything in Null Autos is available over an API, served by the control plane.
The portal and nullctl are both just clients of this API, so any workflow you
see in the product, you can automate.
Surfaces
| Surface | Address | Purpose |
|---|---|---|
| REST API | https://<your-control-plane-host>/api/v1/... | The primary API: emulators, snapshots, tenants, permissions, fleet model |
| gRPC (VHAL) | gRPC subdomain of your control-plane host | Reading and writing vehicle data on emulators |
| Health & metadata | /-/... | Liveness and readiness probes, version, OpenAPI schema |
Your exact hostnames depend on your environment. Ask your tenant admin for your endpoints.
OpenAPI schema
The control plane serves its own OpenAPI schema live at GET /-/openapi/schema
(YAML or JSON via content negotiation). You can use it to generate clients or
explore the full surface. The platform's official TypeScript SDK is generated
from this same schema, so it stays in lockstep with the server.
Authentication
All /api/v1/... endpoints require authentication. The platform accepts several
credential types so the same API works from laptops, pipelines, and clusters:
- Single sign-on bearer tokens
- GitLab personal access tokens
- GitLab CI job tokens (automatic in pipelines)
- Service-account tokens
See Authentication for details and examples.
Request model
- Format: JSON request and response bodies.
- Authorization: every call is checked against the permission model, so you only ever see and act on resources you are entitled to. List endpoints are filtered to your access automatically.
- Async operations: provisioning actions (like creating an emulator) return immediately and you poll a status endpoint. Long-lived data uses streaming (SSE for logs, an authenticated proxy for ADB, gRPC for VHAL).
Quick examples
# Who am I?
curl -H "Authorization: Bearer $TOKEN" \
https://<host>/api/v1/whoami
# List emulators
curl -H "Authorization: Bearer $TOKEN" \
https://<host>/api/v1/emulators
# Launch an emulator from a snapshot
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"snapshot_name":"base-aaos","display_name":"ci-run"}' \
https://<host>/api/v1/emulators
For most use cases the nullctl CLI is the easiest way to
call the API, since it handles auth and polling for you. Drop down to raw HTTP
when you need fine-grained control or a custom integration.