Deploy a new service via API
Deploy and manage services programmatically using the Container Manager APIs
The Container Manager API enables programmatic deployment and management of services, ideal for automation, CI/CD pipelines, and infrastructure-as-code workflows.
Prerequisites
To deploy services via the API, you need:
- A Bearer token for authentication
- The external endpoint URL for your Arango Platform deployment
- For Bring Your Own Code: A
.tar.gzservice package (see Package Your Code) - For Bring Your Own Container: A Docker image URL (public or private)
Deploy a Code-Based Service
Upload Your Archive
Upload your application archive to the storage backend via the FileManager service:
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/filemanager/global/byoc/" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-F "name=<APP_NAME>" \
-F "version=<APP_VERSION>" \
-F "language=python" \
-F "type=Service" \
-F "[email protected]"
| Field | Description | Required |
|---|---|---|
name | Application name identifier (alphanumeric, hyphens, underscores) | Yes |
version | Application version (e.g., 1.0.0) | Yes |
language | Programming language: python or nodejs | Yes |
type | Deployment type: Service | Yes |
file | The .tar.gz archive file | Yes |
The language value must match the runtime of the base image you deploy with:
use python with the py12* images and nodejs with the node22base image
(see Available Base Images).
Success Response:
{
"name": "<APP_NAME>",
"version": "<APP_VERSION>",
"status": "uploaded",
"uploaded_at": "2026-01-01T00:00:00Z"
}
Save the name and version values as you will need them in the deployment step.
Deploy the Service
After uploading your archive, deploy it as a running service:
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/uds" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"app_name": "<APP_NAME>",
"app_version": "<APP_VERSION>",
"env": {
"service_type": "base_type",
"base_image": "py12base",
"app_instance_name": "<APP_INSTANCE_NAME>",
"db_name": "<DATABASE_NAME>"
}
}'
Parameters:
| Parameter | Location | Description | Required |
|---|---|---|---|
app_name | body | Must match the name from upload step | Yes |
app_version | body | Must match the version from upload step | Yes |
service_type | env | Set to base_type | Yes |
base_image | env | Base image name (see Available Base Images) | Yes |
app_instance_name | env | Service instance name (alphanumeric with a 32-character length limit, used in routing) | Yes |
db_name | env | Database name (optional) | No |
The env object also accepts arbitrary additional key-value pairs beyond the
keys documented here. Any extra keys you provide are passed through to your
service as environment variables.
Available Base Images
| Image Name | Description | Upload language |
|---|---|---|
py12base | Python 3.12 base runtime | python |
py12torch | Python 3.12 with PyTorch | python |
py12cugraph | Python 3.12 with cuGraph | python |
node22base | Node.js 22 base runtime | nodejs |
Deploy an Image-Based Service
Provide your own Docker image URL to deploy a service directly, without uploading a code package.
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/uds" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"env": {
"service_type": "derived_type",
"image_url": "<DOCKER_IMAGE_URL>",
"app_instance_name": "<APP_INSTANCE_NAME>",
"db_name": "<DATABASE_NAME>"
}
}'
Parameters:
| Parameter | Location | Description | Required |
|---|---|---|---|
service_type | env | Set to derived_type | Yes |
image_url | env | Full Docker image URL including registry, name, and tag (e.g., docker.io/myorg/myapp:1.0.0) | Yes |
app_instance_name | env | Service instance name (alphanumeric with a 32-character length limit, used in routing) | Yes |
container_port | env | Port your container exposes for HTTP traffic (default: 8000) | No |
db_name | env | Database name (optional) | No |
imagePullSecrets | env | List of Kubernetes Secret names that contain credentials for private Docker registries | No |
Private Registry Authentication
For Docker images hosted in private registries, provide imagePullSecrets
with the names of Kubernetes Secrets that hold your registry credentials.
These secrets must exist in the target namespace before deployment.
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/uds" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"env": {
"service_type": "derived_type",
"image_url": "<PRIVATE_REGISTRY_IMAGE_URL>",
"app_instance_name": "<APP_INSTANCE_NAME>",
"imagePullSecrets": ["<REGISTRY_SECRET_NAME>"]
}
}'
Container Requirements
Your Docker image must:
- Expose an HTTP server on the configured port (default:
8000). - Handle requests at the root path (
/). The platform routes traffic to your container’s root.
Register a Service as an App
If your service serves a user interface (HTML) at the root path (/), you can
register it as an App so it becomes available in the platform’s Apps catalog
and its UI is rendered embedded in the web interface. This works for both
code-based and image-based deployments.
To register a service as an App, add the following properties to the env
object of the deploy request:
| Parameter | Location | Description | Required |
|---|---|---|---|
has_ui | env | Set to "true" to register the service as an App. Pass as a string ("true" / "false"); the value is compared case-insensitively. Defaults to "false". | No |
display_name | env | Name shown for the app in the Apps catalog. Recommended when has_ui is enabled. | No |
description | env | Description shown for the app in the Apps catalog. Recommended when has_ui is enabled. | No |
For example, to deploy a code-based service and register it as an App:
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/uds" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"app_name": "<APP_NAME>",
"app_version": "<APP_VERSION>",
"env": {
"service_type": "base_type",
"base_image": "py12base",
"app_instance_name": "<APP_INSTANCE_NAME>",
"has_ui": "true",
"display_name": "My App",
"description": "A short description of my app"
}
}'
For more about the App requirements and how to open an app from the catalog, see Host a UI with Apps.
Service Access
Once deployed, your service is accessible via HTTP at a specific endpoint pattern which depends on whether your service is database-scoped or global.
If you provided db_name during deployment, your service is accessible at:
If you did not provide db_name, your service is accessible at:
All HTTP requests to these paths are routed to your container’s service.
List Deployed Services
Get a list of the deployed services, including services registered as Apps:
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/list_services" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{}'
The request body is optional. To narrow the results, pass a JSON object with
labels to filter services by their labels:
curl -X POST "https://<EXTERNAL_ENDPOINT>:8529/_platform/acp/v1/list_services" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"labels": {"<KEY>": "<VALUE>"}}'
For services registered as Apps, the App metadata is available under each
service’s serviceMeta.udsMeta object:
| Property | Description |
|---|---|
hasUi | Whether the service is registered as an App (serves a UI at /) |
displayName | Name shown for the app in the Apps catalog |
description | Description shown for the app in the Apps catalog |
Response (excerpt):
{
"services": [
{
"serviceMeta": {
"udsMeta": {
"hasUi": true,
"displayName": "My App",
"description": "A short description of my app"
}
}
}
]
}
Manage Uploaded Files
List All Uploaded Services
Get a list of all uploaded services:
Query Parameters:
| Parameter | Description | Required |
|---|---|---|
name | Filter by service name | No |
language | Filter by language (python or nodejs) | No |
type | Filter by type (Service or Job) | No |
limit | Maximum results to return (default: 100) | No |
offset | Pagination offset (default: 0) | No |
Response:
{
"services": [
{
"name": "my-service",
"version": "1.0.0",
"language": "python",
"type": "Service",
"storage_location": "file_manager:byoc:my-service:v1.0.0:service.tar.gz",
"size": 1024,
"uploaded_at": "2026-01-01T00:00:00Z",
"safe_to_delete": false
}
],
"total": 1,
"limit": 100,
"offset": 0
}
List Versions of a Service
Get all versions of a specific service:
Query Parameters:
| Parameter | Description | Required |
|---|---|---|
limit | Maximum results to return (default: 100) | No |
offset | Pagination offset (default: 0) | No |
Response:
{
"name": "my-service",
"versions": [
{
"version": "1.0.0",
"language": "python",
"type": "Service",
"size": 1024,
"uploaded_at": "2026-01-01T00:00:00Z"
},
{
"version": "2.0.0",
"language": "python",
"type": "Service",
"size": 2048,
"uploaded_at": "2026-01-02T00:00:00Z"
}
],
"total": 2,
"limit": 100,
"offset": 0
}
Get File Information
Get detailed information about a specific service version:
Response:
{
"name": "my-service",
"version": "1.0.0",
"language": "python",
"type": "Service",
"storage_location": "file_manager:byoc:my-service:v1.0.0:service.tar.gz",
"size": 1024,
"uploaded_at": "2026-01-01T00:00:00Z",
"safe_to_delete": false
}
Download Service File
Download the uploaded service file:
curl -X GET "https://<EXTERNAL_ENDPOINT>:8529/_platform/filemanager/global/byoc/<SERVICE_NAME>/<VERSION>/download" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-o service.tar.gz
The file content is streamed back with Content-Type: application/octet-stream.
Complete Examples
Code-Based Deployment
A complete workflow for uploading and deploying a database-scoped service
from a code package. The example uses a Python service. For a Node.js service,
upload with language=nodejs and deploy with "base_image": "node22base":
#!/bin/bash
ENDPOINT="https://your-platform.example.com:8529"
TOKEN="your_jwt_token"
SERVICE_NAME="recommendation-engine"
SERVICE_VERSION="1.0.0"
INSTANCE_NAME="recommendation-api"
DATABASE="mydb"
# Step 1: Upload service package
echo "Uploading service package..."
curl -X POST "$ENDPOINT/_platform/filemanager/global/byoc/" \
-H "Authorization: Bearer $TOKEN" \
-F "name=$SERVICE_NAME" \
-F "version=$SERVICE_VERSION" \
-F "language=python" \
-F "type=Service" \
-F "file=@${SERVICE_NAME}.tar.gz"
# Step 2: Deploy the service
echo "Deploying service..."
curl -X POST "$ENDPOINT/_platform/acp/v1/uds" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"app_name\": \"$SERVICE_NAME\",
\"app_version\": \"$SERVICE_VERSION\",
\"env\": {
\"service_type\": \"base_type\",
\"base_image\": \"py12base\",
\"app_instance_name\": \"$INSTANCE_NAME\",
\"db_name\": \"$DATABASE\"
}
}"
echo "Service deployed successfully!"
echo "Access your service at: $ENDPOINT/_service/uds/_db/$DATABASE/$INSTANCE_NAME/"
Container-Based Deployment
A complete workflow for deploying a service from a Docker image:
#!/bin/bash
ENDPOINT="https://your-platform.example.com:8529"
TOKEN="your_jwt_token"
IMAGE_URL="docker.io/myorg/my-web-service:1.0.0"
INSTANCE_NAME="my-web-service"
DATABASE="mydb"
echo "Deploying container image..."
curl -X POST "$ENDPOINT/_platform/acp/v1/uds" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"env\": {
\"service_type\": \"derived_type\",
\"image_url\": \"$IMAGE_URL\",
\"app_instance_name\": \"$INSTANCE_NAME\",
\"db_name\": \"$DATABASE\"
}
}"
echo "Service deployed successfully!"
echo "Access your service at: $ENDPOINT/_service/uds/_db/$DATABASE/$INSTANCE_NAME/"
Web Interface Alternative
For visual deployment and management, see Deploy via Web Interface.
