Authorization: Bearer <api_token> header
described in Getting Started, and a base URL of https://sdk.localops.co.
Onboard a bring-your-own-cloud (BYOC) customer - headless
The end to end recipe for a BYOC edition: your product running inside the customer’s own AWS, GCP or Azure account. Every step below is an API call, so onboarding a customer is a script you run once per customer rather than a walk through the console. The recipes further down this page cover each step in more detail.Provision the environment in their cloud
POST /v1/environments with the customer’s cloud_connection_id, the project_id to file it under, and the
region they want - aws-us-east-1, gcp-us-central1, and so on. Pass custom_cidr when their network team needs
the VPC in a particular range.Then poll GET /v1/environments/{envId} until state is available.POST /v1/environments is badged COMING SOON and returns 404 today - create the environment in the console
for now. Every step after this one is live.Add your services
POST /v1/environments/{envId}/services once per service - API, workers, cron jobs, frontend. Each one can come
from a GitHub or GitLab repo, a Docker image or a Helm chart, with its own replica_count, CPU and memory.Keep each data.service.id - there is no list endpoint to look them up again. Adding a service to a customer later
is the same call.See Create a Helm service and deploy it and
Deploy a git service from CI.Set their secrets
PUT /v1/environments/{envId}/secrets for values every service in the environment shares, and
PUT /v1/environments/{envId}/services/{serviceId}/secrets for the ones scoped to a single service.This is where per customer configuration lives - their database URLs, their API keys, their license terms.See Update secrets safely - these writes replace the whole set.Deploy
POST /v1/environments/{envId}/services/{serviceId}/deploy with a commit_id, a docker_image_tag or a
helm_chart_version, then poll GET /v1/deployments/{deploymentId} until success or failed.See Deploy a git service from CI.Attach their domain
POST /v1/environments/{envId}/services/{serviceId}/custom-domains returns the exact DNS records for the customer
to create. Once they resolve, POST .../custom-domains/{customDomainId}/verify checks them and cuts traffic over.See Attach a custom domain.Hand over the network details
GET /v1/environments/{envId} returns the ingress_host to point DNS at, the public_nat_ips to allowlist and
the svc_role_arn to name in their resource policies - the three things the customer’s network and security teams
ask for during review.See Point your own DNS and allowlists at an environment.Ship a release to every customer
Once customers are onboarded, a rollout is the same call against each environment id:deployment_id, so you can gate the next customer on the previous one reaching success and stage
the rollout across your install base.
Point your own DNS and allowlists at an environment
GET /v1/environments/{envId} reads three fields live from the environment’s infrastructure on every call. They are
what you need to connect your own DNS, firewalls and cloud IAM to a LocalOps environment.
All three are empty until the environment is provisioned, so poll until the one you need is set.
svc_role_arn is an identifier, not a credential. Naming it in a resource policy grants nothing until you also set up
the trust in your own account. And public_nat_ips can change, so re-read it after infrastructure changes rather than
caching it indefinitely.Create a Helm service and deploy it
Create the service
POST /v1/environments/{envId}/services with source: "helm_chart" and deploy_now: false.Keep deploy_now off for Helm services. It deploys without a chart version, so an explicit deploy is almost always
what you want.data.service.id from the response - there is no list endpoint to look it up again.Write service secrets
PUT /v1/environments/{envId}/services/{serviceId}/secrets, if the service needs any.Deploy a chart version
POST /v1/environments/{envId}/services/{serviceId}/deploy with {"helm_chart_version": "1.4.0"}.Keep data.deployment_id from the response.Poll the deployment
GET /v1/deployments/{deploymentId} until state is success or failed.Service names on create accept letters and spaces only. Digits, hyphens and underscores are rejected. Updates are
laxer and also allow hyphens.
Deploy a git service from CI
For a GitHub or GitLab service, deploy the head of the configured branch by sending an empty object:GET /v1/deployments/{deploymentId}. The deployment row is created synchronously, so you always get an id
back immediately even though the rollout itself runs in the background - a rollout failure shows up as
state: "failed", not as an error on the deploy call.
For a docker_image service, send docker_image_tag instead. For helm_chart, send helm_chart_version.
Deploy a pull request preview
Check the parent service
The parent service must use the
github source, be of type web, and have enable_previews turned on. Your plan
must include preview environments, otherwise the call returns 403.Turn previews on with PATCH /v1/environments/{envId}/services/{serviceId} and {"enable_previews": true}.Trigger the preview deploy
commit_id, branch and pr_number are all required in preview mode, and docker_image_tag and
helm_chart_version must be absent.Use the returned preview service
The response carries
service_id, service_name, origin, pr_number and is_new - not a deployment id.A preview service is created for the pull request the first time (is_new: true) and reused on later calls
(is_new: false). It inherits the parent’s type, resources, port and node group, and has auto_deploy turned on.Poll the preview service
GET /v1/environments/{envId}/services/{serviceId} with the returned service_id, until state is running.Attach a custom domain
Register the domain
POST /v1/environments/{envId}/services/{serviceId}/custom-domains with {"domain": "app.example.com"}.The response contains dns_records, each with record_name, record_type and record_value.Create the DNS records
Add every returned record in your DNS provider - both the certificate validation record and the traffic routing
record.
Verify
POST /v1/environments/{envId}/services/{serviceId}/custom-domains/{customDomainId}/verify.Confirm
GET /v1/environments/{envId}/services/{serviceId}/custom-domains until active_domain.state is deployed.Verifying a new domain retires the service’s previously active domain.force-deploy is the escape hatch:
CUSTOM_DOMAIN_FORCE_DEPLOY.
Wire one service to another
Services inside the same environment reach each other over an in cluster DNS alias.Read the alias
GET /v1/environments/{envId}/services/{serviceId} returns svc_alias. It is empty until the service is
provisioned, so poll until it is set.Publish it as a secret
PUT /v1/environments/{envId}/services/{serviceId}/secrets on the consuming service, with the alias as the host -
for example DB_HOST.Redeploy the consumer
Secret writes do not roll themselves out. Trigger a deployment for the consuming service.
ops_dependencies - the cloud resources the service declares in its
ops.json. Each one lists the environment variables it injects, so you can discover
what a service already gets without reading its repo:
$... tokens are resolved when the variables are injected into your container. The API returns them as declared.
Update secrets safely
Both secret endpoints are a full replacement, not a merge. Any key you leave out of the array is removed.Read
GET /v1/environments/{envId}/secrets, or the service level equivalent.Modify
Change or add entries in the array you just read. Keys must be non empty and unique - a duplicate is rejected with
422 and Duplicate secret key: <key>.Write the whole set back
PUT the complete array. Validation runs before anything is written, so a rejected request changes nothing.Delete a service
Remove protection
A protected service returns
409 on delete. Clear it first with
PATCH /v1/environments/{envId}/services/{serviceId} and {"is_protected": false}.Delete
DELETE /v1/environments/{envId}/services/{serviceId} returns 202 {"message": "accepted"}, meaning the teardown
was accepted and started. A non 2xx means nothing was torn down.Poll to completion
GET /v1/environments/{envId}/services/{serviceId} through delete_queued, deleting and deleted, or
delete_failed on failure.