Skip to main content

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​

MethodPathAccess
GET/targets?domain_name=Read
POST/targetsWrite
PUT/targets/:hashed_idWrite
DELETE/targets/:hashed_idWrite

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"
}
FieldTypeDescription
hashed_idstringThe target's id
domain_namestringThe domain it routes
target_typestringApp, Bucket, Cluster or LoadBalancer
cluster_id, cluster_namestringFor a Cluster or LoadBalancer target, the cluster's id and name
app_id, app_name, app_labelstringFor an App target, the app's id, name and label
bucket_id, bucket_namestringFor a Bucket target, the bucket's id and name
loadbalancer_ipstringFor 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, protocolstring, string, integer, stringFor 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
pathstringThe path on the domain that is routed, for example / or /api. Always / for a Bucket or LoadBalancer target
target_pathstringThe path requests are sent to on the service. Defaults to path
created_atstringWhen 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 parameterRequiredDescription
domain_nameYesThe 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​

FieldTypeRequiredDescription
domain_namestringYesA domain of the account
target_typestringNoApp, Bucket, Cluster or LoadBalancer. Default Cluster
pathstringNoThe path on the domain. Default /. Must start with / and use only letters, digits, /, _, . and -. Must be / for Bucket and LoadBalancer
target_pathstringNoThe path on the service. Default: the same as path. Same rules
app_idstringFor AppThe app's hashed_id. The app must be Ready or Paused
bucket_idstringFor BucketThe bucket's hashed_id. The bucket must be Ready, with its static website on
cluster_idstringFor Cluster and LoadBalancerThe cluster's hashed_id. For LoadBalancer, the cluster must be Ready or Paused
cluster_namestringFor ClusterThe cluster's cluster_name, exactly as in GET /clusters
namespacestringFor Cluster and LoadBalancerThe Service's namespace
servicestringFor Cluster and LoadBalancerThe Service's name. For LoadBalancer, a Service of type LoadBalancer that has an IP
portintegerFor ClusterThe Service port
protocolstringNoThe 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.

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": "/"}'
Response
{"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​

StatusFieldMessage
400domain_nameDomain name is required
400path, target_pathPath must start with / and may only contain letters, numbers and / _ . -, Target path must start with / and may only contain letters, numbers and / _ . -
400app_idApp is required
400bucket_idBucket is required
400path, target_pathA 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)
400service, namespace, portService is required, Namespace is required, Valid port is required
400cluster_id, service, path, target_pathCluster 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": "/"
}'
Response
{"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"
Response
{"message": "Target deleted successfully"}

403 for read only tokens and Restricted members, 404 Not Found (plain text) for an unknown target.