Targets API endpoints
A target routes requests for a domain and path, such as https://example.com/ or https://example.com/api, to an app, to a Service in one of your Kubernetes clusters, or to a bucket's static website. Cloider sets up the routing and the HTTPS certificate for you. A LoadBalancer target instead gives a custom domain an A record to a LoadBalancer's IP, see Point a domain at a LoadBalancer. These endpoints list, create, change and delete targets.
All paths are relative to https://cloider.com/api. See Targets for how routing works.
At a glance
| Method | Path | Access |
|---|---|---|
| GET | /targets?domain_name= | Read |
| POST | /targets | Write |
| PUT | /targets/:hashed_id | Write |
| DELETE | /targets/:hashed_id | Write |
The target object
{
"hashed_id": "x4v7n",
"domain_name": "example.com",
"target_type": "Cluster",
"cluster_id": "p8w2d",
"cluster_name": "production",
"app_id": "",
"app_name": "",
"app_label": "",
"bucket_id": "",
"bucket_name": "",
"loadbalancer_ip": "",
"namespace": "shop",
"service": "api",
"port": 8080,
"protocol": "TCP",
"path": "/api",
"target_path": "/",
"created_at": "2026-10-03T17:41:20.551093Z"
}
| Field | Type | Description |
|---|---|---|
hashed_id | string | The target's id |
domain_name | string | The domain it routes |
target_type | string | App, Bucket, Cluster or LoadBalancer |
cluster_id, cluster_name | string | For a Cluster or LoadBalancer target, the cluster's id and name |
app_id, app_name, app_label | string | For an App target, the app's id, name and label |
bucket_id, bucket_name | string | For a Bucket target, the bucket's id and name |
loadbalancer_ip | string | For a LoadBalancer target, the IP the domain's A record points at. Empty while the LoadBalancer has none, when the domain has no A record |
namespace, service, port, protocol | string, string, integer, string | For a Cluster target, the Kubernetes Service in your cluster that requests go to. For an App target, namespace and service are empty, and port is the app's port. For a Bucket target, namespace and service are empty too. For a LoadBalancer target, namespace and service name the LoadBalancer, port is 0 and protocol is empty |
path | string | The path on the domain that is routed, for example / or /api. Always / for a Bucket or LoadBalancer target |
target_path | string | The path requests are sent to on the service. Defaults to path |
created_at | string | When the target was created |
A domain can route each path to one target. The first target on a domain makes its status Active.
List a domain's targets
GET /targets?domain_name=:domain_name
Returns the targets of one domain, newest first.
Access: any token.
| Query parameter | Required | Description |
|---|---|---|
domain_name | Yes | The domain, for example example.com |
curl "https://cloider.com/api/targets?domain_name=example.com" \
-H "Authorization: Bearer $CLOIDER_TOKEN"
The response is a list of target objects. Without domain_name the answer is 400 Domain name is required; for a domain that isn't the account's, 403 You don't have permission to access targets for this domain.
Create a target
POST /targets
Routes a domain path to an app, a cluster service or a bucket's website. The route and its certificate are set up in the background after the request returns.
Access: Read & Write token.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
domain_name | string | Yes | A domain of the account |
target_type | string | No | App, Bucket, Cluster or LoadBalancer. Default Cluster |
path | string | No | The path on the domain. Default /. Must start with / and use only letters, digits, /, _, . and -. Must be / for Bucket and LoadBalancer |
target_path | string | No | The path on the service. Default: the same as path. Same rules |
app_id | string | For App | The app's hashed_id. The app must be Ready or Paused |
bucket_id | string | For Bucket | The bucket's hashed_id. The bucket must be Ready, with its static website on |
cluster_id | string | For Cluster and LoadBalancer | The cluster's hashed_id. For LoadBalancer, the cluster must be Ready or Paused |
cluster_name | string | For Cluster | The cluster's cluster_name, exactly as in GET /clusters |
namespace | string | For Cluster and LoadBalancer | The Service's namespace |
service | string | For Cluster and LoadBalancer | The Service's name. For LoadBalancer, a Service of type LoadBalancer that has an IP |
port | integer | For Cluster | The Service port |
protocol | string | No | The port's protocol as listed by GET /clusters/services, for example TCP |
GET /clusters/services lists every Service with its namespace, ports, type and, for a LoadBalancer, its ip; see Clusters.
- Route to an app
- Route to a bucket website
- Point at a LoadBalancer
- Route to a cluster service
curl -X POST https://cloider.com/api/targets \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain_name": "blog.example.com", "target_type": "App", "app_id": "a8q2w", "path": "/"}'
curl -X POST https://cloider.com/api/targets \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain_name": "docs.example.com", "target_type": "Bucket", "bucket_id": "s3w8q"}'
curl -X POST https://cloider.com/api/targets \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain_name": "play.example.com", "target_type": "LoadBalancer", "cluster_id": "p8w2d", "namespace": "games", "service": "server"}'
The domain must be a custom domain with no other targets. Its A record is created with the target and deleted with it. Cloider issues no certificate for the domain: TLS, and whatever routes requests behind the LoadBalancer, are yours to manage.
curl -X POST https://cloider.com/api/targets \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domain_name": "example.com",
"target_type": "Cluster",
"cluster_id": "p8w2d",
"cluster_name": "production",
"namespace": "shop",
"service": "api",
"port": 8080,
"protocol": "TCP",
"path": "/api",
"target_path": "/"
}'
{"hashed_id": "x4v7n", "domain_name": "example.com", "message": "Target created successfully"}
For a custom domain, the domain's nameservers must point to Cloider for the route to be reachable; see Expose services and Domains for apps.
Errors
| Status | Field | Message |
|---|---|---|
400 | domain_name | Domain name is required |
400 | path, target_path | Path must start with / and may only contain letters, numbers and / _ . -, Target path must start with / and may only contain letters, numbers and / _ . - |
400 | app_id | App is required |
400 | bucket_id | Bucket is required |
400 | path, target_path | A bucket website is served at the root of its domain, the path must be /, A bucket website is served at the root of its domain, the target path must be / (Bucket targets) |
400 | service, namespace, port | Service is required, Namespace is required, Valid port is required |
400 | cluster_id, service, path, target_path | Cluster is required, LoadBalancer is required, A LoadBalancer takes the whole domain, the path must be /, A LoadBalancer takes the whole domain, the target path must be / (LoadBalancer targets) |
400 | _ | A LoadBalancer target needs a custom domain., A LoadBalancer target takes the whole domain. Delete the domain's other targets first, or use another domain., This domain points at a LoadBalancer, which takes the whole domain. Delete that target first, or use another domain. |
400 | _ | This cluster is not ready yet. Wait until it is running, then add the target., This LoadBalancer has no IP yet. Wait until it gets one, then add the target., The domain has an A, AAAA, ALIAS or CNAME record of its own. Delete it from the domain's DNS records first, then add the target. |
400 | _ | Invalid target type specified |
400 | _ | This path is already in use on this domain. Please choose a different path. |
400 | _ | This app is not ready yet. Wait until it finishes deploying, then add the target. |
400 | _ | This bucket is not ready yet. Wait until it is created, then add the target., Turn on the bucket's website first, from its Settings. |
400 | _ | Service and namespace names are too long for this cluster (combined limit exceeded), This app's name is too long to be exposed on a domain. |
400 | _ | Your account is suspended. Upgrade to a paid plan to continue using our services. |
403 | _ | This API token is read only! |
404 | _ | App not found!, Bucket not found!, LoadBalancer not found! ..., or Not Found (plain text) for a domain or cluster that isn't the account's |
Change a target
PUT /targets/:hashed_id
Changes where a target routes: its domain, path, target path, and the app, service or bucket. The body is the same as for creating a target, and every field is applied, so send the complete target.
Access: Read & Write token.
curl -X PUT https://cloider.com/api/targets/x4v7n \
-H "Authorization: Bearer $CLOIDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"domain_name": "example.com",
"target_type": "Cluster",
"cluster_id": "p8w2d",
"cluster_name": "production",
"namespace": "shop",
"service": "api-v2",
"port": 8080,
"protocol": "TCP",
"path": "/api",
"target_path": "/"
}'
{"hashed_id": "x4v7n", "domain_name": "example.com", "message": "Target updated successfully"}
The errors are those of creating a target, and Operation failed, Couldn't update the target!.
Delete a target
DELETE /targets/:hashed_id
Removes the route. The app, service or bucket website keeps running but is no longer reachable on that domain and path. When a domain loses its last target, its status becomes Suspended.
Access: Read & Write token.
curl -X DELETE https://cloider.com/api/targets/x4v7n \
-H "Authorization: Bearer $CLOIDER_TOKEN"
{"message": "Target deleted successfully"}
403 for read only tokens and Restricted members, 404 Not Found (plain text) for an unknown target.
Related
- Targets and HTTPS certificates
- Static websites and the website endpoints of buckets
- Expose services from a cluster
- cloider target and the cloider_target Terraform resource