Provisioning API
Programmatically provision agents, manage environment variables, and inject custom build scripts for enterprise deployments.
Base URL: https://api.maritime.sh/api/v1
Auth: All provisioning endpoints require an X-API-Key header with a maritime API key (mk_...).
Quick Start
Provision an agent and deploy in a few lines.
# Set your API key
export MARITIME_API_KEY="mk_your_key_here"
# 1. Provision an agent
curl -s -X POST https://api.maritime.sh/api/v1/provision \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-agent",
"image": "openclaw",
"image_name": "python:3.11-slim",
"auto_deploy": false
}'
# Save the agent_id from the response, then:
# 2. Deploy the agent
curl -s -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/deploy \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json"
# 3. Check status
curl -s https://api.maritime.sh/api/v1/agents/AGENT_ID \
-H "X-API-Key: $MARITIME_API_KEY"API Key Management
Create and manage API keys from the dashboard. These endpoints use session authentication (cookies), not API key auth.
Create API Key
/api/v1/keys| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Human-readable name for this key |
| scopes | string[] | No | Scopes: provision, deploy, secrets, manage. Default: all. |
| expires_in_days | integer | null | No | Key expiry in days. Null = never expires. |
curl -X POST https://api.maritime.sh/api/v1/keys \
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "production-pipeline",
"scopes": ["provision", "deploy", "manage"],
"expires_in_days": 90
}'{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "production-pipeline",
"key_prefix": "mk_aBcDeFgH",
"scopes": ["provision", "deploy", "manage"],
"is_active": true,
"last_used_at": null,
"expires_at": "2026-06-13T10:30:00Z",
"created_at": "2026-03-15T10:30:00Z",
"raw_key": "mk_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abc"
}Store the raw_key securely. It is returned only once at creation time and cannot be retrieved again.
List API Keys
/api/v1/keyscurl -s https://api.maritime.sh/api/v1/keys \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"Revoke API Key
/api/v1/keys/{key_id}curl -X DELETE https://api.maritime.sh/api/v1/keys/KEY_ID \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
# Returns 204 No Content on successProvisioning
Provision Agent
/api/v1/provisionscope: provision| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Agent name |
| description | string | No | Agent description |
| image | string | No | Framework: openclaw, crewai, langgraph, docker, custom, auto |
| image_name | string | No | Docker image (e.g. python:3.11-slim) |
| repo_url | string | No | GitHub repo URL for source builds |
| branch | string | No | Git branch (default: main) |
| auto_deploy | boolean | No | Deploy immediately (default: true) |
| env_vars | object | No | Non-secret env vars as key-value pairs |
curl -X POST https://api.maritime.sh/api/v1/provision \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "customer-support-bot",
"image": "openclaw",
"image_name": "python:3.11-slim",
"repo_url": "https://github.com/acme/support-agent",
"auto_deploy": true,
"env_vars": {
"LOG_LEVEL": "info",
"REGION": "us-east-1"
}
}'{
"agent_id": "7f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"name": "customer-support-bot",
"status": "deploying",
"deployment_id": "d8e9f0a1-b2c3-4d5e-6f7a-8b9c0d1e2f3a",
"message": "Agent provisioned."
}List Agents
/api/v1/agentsscope: provisioncurl -s https://api.maritime.sh/api/v1/agents \
-H "X-API-Key: $MARITIME_API_KEY"Get Agent Status
/api/v1/agents/{agent_id}scope: provisioncurl -s https://api.maritime.sh/api/v1/agents/AGENT_ID \
-H "X-API-Key: $MARITIME_API_KEY"Custom Build Files
Upload Custom Files
/api/v1/agents/{agent_id}/filesscope: deployInject files into the agent container. By default, files are placed in /maritime/scripts/ and shell scripts are executed after deploy. You can customize the target directory and control whether scripts run on deploy.
| Parameter | Type | Required | Description |
|---|---|---|---|
| files | CustomFile[] | Yes | Array of files to inject |
| files[].path | string | Yes | Filename or relative path (e.g. install-tools.sh, config/app.toml) |
| files[].content | string | Yes | File content. Include shebang for scripts. |
| files[].executable | boolean | No | chmod +x the file (default: true) |
| files[].run_on_deploy | boolean | No | Execute .sh files after deploy (default: true). Set false to only place the file. |
| files[].target_dir | string | No | Directory inside the container (default: /maritime/scripts). E.g. /app/config, /data. |
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/files \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"files": [
{
"path": "install-deps.sh",
"content": "#!/bin/bash\nset -e\napt-get update -qq\napt-get install -y -qq ffmpeg imagemagick\npip install -q pandas numpy scikit-learn",
"executable": true,
"run_on_deploy": true,
"target_dir": "/maritime/scripts"
},
{
"path": "app.toml",
"content": "[server]\nhost = \"0.0.0.0\"\nport = 8080",
"executable": false,
"run_on_deploy": false,
"target_dir": "/app/config"
}
]
}'
# Response: 201 Created
# {"agent_id": "...", "files_count": 2, "message": "Uploaded 2 custom file(s)..."}Environment Variables
Manage an agent's environment variables. Secret values are stored encrypted and always returned masked. Changes apply on the agent's next container boot (redeploy or restart to pick them up).
List Environment Variables
/api/v1/agents/{agent_id}/env[
{ "key": "OPENAI_API_KEY", "value": "sk-••••••••", "is_secret": true },
{ "key": "LOG_LEVEL", "value": "debug", "is_secret": false }
]Set an Environment Variable
/api/v1/agents/{agent_id}/envscope: manageCreates the variable, or updates it if the key already exists (upsert).
| Parameter | Type | Required | Description |
|---|---|---|---|
| key | string | Yes | Variable name |
| value | string | Yes | Variable value |
| is_secret | boolean | No | Encrypt at rest and mask in responses (default: false) |
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/env \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"key": "OPENAI_API_KEY", "value": "sk-...", "is_secret": true}'
# Response: 201 Created
# {"key": "OPENAI_API_KEY", "value": "sk-••••••••", "is_secret": true}Update / Delete an Environment Variable
/api/v1/agents/{agent_id}/env/{key}scope: manage/api/v1/agents/{agent_id}/env/{key}scope: manage# Update (404 if the key does not exist):
curl -X PUT https://api.maritime.sh/api/v1/agents/AGENT_ID/env/LOG_LEVEL \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"value": "info"}'
# Delete (returns 204 No Content):
curl -X DELETE https://api.maritime.sh/api/v1/agents/AGENT_ID/env/LOG_LEVEL \
-H "X-API-Key: $MARITIME_API_KEY"Lifecycle Management
Deploy / Redeploy
/api/v1/agents/{agent_id}/deployscope: deployReturns 202 Accepted: the deploy runs asynchronously. Poll GET /api/v1/agents/{agent_id} until the status leaves deploying.
| Parameter | Type | Required | Description |
|---|---|---|---|
| image_name | string | No | Override Docker image |
| repo_url | string | No | Override repo URL |
| branch | string | No | Override git branch |
# Deploy with defaults (uses provisioned settings)
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/deploy \
-H "X-API-Key: $MARITIME_API_KEY"
# Deploy a specific branch
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/deploy \
-H "X-API-Key: $MARITIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"branch": "staging"}'Start / Stop / Restart
/api/v1/agents/{agent_id}/startscope: deploy/api/v1/agents/{agent_id}/stopscope: deploy/api/v1/agents/{agent_id}/restartscope: deploy# Start
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/start \
-H "X-API-Key: $MARITIME_API_KEY"
# Stop
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/stop \
-H "X-API-Key: $MARITIME_API_KEY"
# Restart
curl -X POST https://api.maritime.sh/api/v1/agents/AGENT_ID/restart \
-H "X-API-Key: $MARITIME_API_KEY"Teardown
/api/v1/agents/{agent_id}scope: manageStops the container, removes the volume, and deletes the agent record.
curl -X DELETE https://api.maritime.sh/api/v1/agents/AGENT_ID \
-H "X-API-Key: $MARITIME_API_KEY"
# Returns 204 No Content on successLogs & Deployments
Get Agent Logs
/api/v1/agents/{agent_id}/logs| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Max entries to return (default: 100, max: 1000) |
| level | string | No | Filter by level: info, warning, error |
curl -s "https://api.maritime.sh/api/v1/agents/AGENT_ID/logs?limit=50&level=error" \
-H "X-API-Key: $MARITIME_API_KEY"[
{
"id": "a1b2c3d4...",
"level": "error",
"message": "Container exited with code 1",
"source": "system",
"timestamp": "2026-03-22T14:30:00Z"
}
]Get Deployment History
/api/v1/agents/{agent_id}/deployments| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Max entries to return (default: 10, max: 50) |
curl -s "https://api.maritime.sh/api/v1/agents/AGENT_ID/deployments?limit=5" \
-H "X-API-Key: $MARITIME_API_KEY"[
{
"id": "d8e9f0a1...",
"status": "success",
"source": "docker",
"branch": null,
"build_log": "Pulling image ghcr.io/openclaw/openclaw:latest...\nContainer created: abc123...\nCustom files injected: install-deps.sh → /maritime/scripts (executed)\nDeploy complete.",
"started_at": "2026-03-22T14:00:00Z",
"completed_at": "2026-03-22T14:00:45Z"
}
]Billing
There is no billing surface on this API. Every account is on a seat plan, managed from the Billing page in the dashboard: the plan sets how many agents you may run, and add-ons (extra RAM, extra SSD, always-on) are flat monthly prices per agent. Agents you provision here count against the same plan. See Billing & plans.
API Key Scopes
| Scope | Grants Access To |
|---|---|
| provision | Provision new agents, list agents, get agent status |
| deploy | Deploy, start, stop, restart agents; upload custom files |
| manage | All of the above, plus teardown/delete agents |
Error Responses
| Status | Meaning |
|---|---|
| 401 | Missing, invalid, revoked, or expired API key |
| 403 | API key lacks the required scope for this endpoint |
| 404 | Agent not found, or agent belongs to a different user |
| 409 | Deploy already in progress for this agent |
Full End-to-End Example
Complete scripts you can copy, fill in your key, and run.
"""
maritime_provision.py: Provision, add build scripts, deploy.
pip install requests
"""
import requests
API_KEY = "mk_your_key_here"
BASE = "https://api.maritime.sh/api/v1"
H = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# ── 1. Provision (env var secret values are encrypted at rest) ──
r = requests.post(f"{BASE}/provision", headers=H, json={
"name": "fraud-detector",
"image": "openclaw",
"image_name": "python:3.11-slim",
"repo_url": "https://github.com/acme/fraud-detector",
"auto_deploy": False,
"env_vars": {
"LOG_LEVEL": "info",
"OPENAI_API_KEY": "sk-proj-...",
"DATABASE_URL": "postgresql://user:pass@host:5432/db",
},
}).json()
agent_id = r["agent_id"]
print(f"1. Provisioned: {agent_id}")
# ── 2. Custom build files ──
r = requests.post(f"{BASE}/agents/{agent_id}/files", headers=H, json={
"files": [{
"path": "install-deps.sh",
"content": "#!/bin/bash\nset -e\napt-get update -qq\napt-get install -y -qq ffmpeg\npip install -q torch",
"executable": True,
"run_on_deploy": True,
}],
}).json()
print(f"2. Files: {r['message']}")
# ── 3. Deploy ──
r = requests.post(f"{BASE}/agents/{agent_id}/deploy", headers=H).json()
print(f"3. Deploy: {r['message']} (deployment_id: {r['deployment_id']})")
# ── 4. Poll status ──
import time
for _ in range(30):
status = requests.get(f"{BASE}/agents/{agent_id}", headers=H).json()["status"]
print(f" Status: {status}")
if status in ("active", "error"):
break
time.sleep(5)