Create a service from an upload
Create a new service from a base64-encoded source archive. Use reupload to update an existing upload service.
Request & response examples
curl --fail-with-body --request POST \ 'https://app.helicarrier.xyz/api/projects/my-project/services/upload-b64?env=staging' \ -H "Authorization: Bearer $HELI_API_KEY" \ -H 'Content-Type: application/json' \ --data '{ "name": "my-service", "archiveBase64": "BASE64_ENCODED_SOURCE_ARCHIVE"}'const response = await fetch( "https://app.helicarrier.xyz/api/projects/my-project/services/upload-b64?env=staging", { method: "POST", headers: { Authorization: `Bearer ${process.env.HELI_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "name": "my-service", "archiveBase64": "BASE64_ENCODED_SOURCE_ARCHIVE" }) });const data = await response.json();if (!response.ok) { throw new Error(`HTTP ${response.status}: ${data.error}`);}// Inspect data; avoid logging secret responses.import osimport requests
response = requests.request( "POST", "https://app.helicarrier.xyz/api/projects/my-project/services/upload-b64?env=staging", headers={ "Authorization": f"Bearer {os.environ['HELI_API_KEY']}" }, json={ "name": "my-service", "archiveBase64": "BASE64_ENCODED_SOURCE_ARCHIVE" }, timeout=30,)response.raise_for_status()data = response.json()# Inspect data; avoid logging secret responses.{ "service": { "id": "svc_example", "name": "my-app", "slug": "my-app", "sourceType": "upload", "status": "running", "planKey": "heli-s1", "projectId": "prj_example", "environmentId": "env_example" }, "deploymentId": "dep_example"}Illustrative values · selected fields
Path parameters
projectSlugstringrequiredTarget project slug.
Query parameters
envstringoptionalTarget environment slug (e.g. dev, staging, production). This route takes the environment as a query argument, not in the body. Optional for a normal key — the project's default environment is used. REQUIRED when your API key is restricted to specific environments; call whoami to see whether yours is.
Request body
namestringrequiredService name.
runtimeModestringoptionalweb | worker | static | cron (default web).
archiveBase64stringrequiredThe build context as a base64-encoded .tar.gz (or .zip) of your project folder.
rootDirstringoptionalSubdir the app lives in (optional).
installCommandstringoptionalInstall override (optional).
buildCommandstringoptionalBuild override (optional).
startCommandstringoptionalStart command / for static, the output dir (optional).
internalPortintegeroptionalPort the app listens on (optional).
planKeystringoptionalPlan key from list_plans (e.g. heli-static). Prefer passing this explicitly so the service runs on the intended plan; if omitted, the cheapest plan matching the service type is applied.
Response 201
This creates a new service each time. To ship a new version to an existing upload service, use Reupload service instead. Exclude dependencies and repository metadata from the archive.
Examples show selected response fields with illustrative values. Your response can contain additional fields.
serviceobjectChild fields
idstringUnique identifier of this resource.
namestringHuman-readable resource name.
slugstringURL-safe resource identifier.
sourceTypestringSource used to build or run the service.
statusstringCurrent state of the resource or operation.
planKeystringPlan identifier from the plan catalog.
projectIdstringProject that owns the resource.
environmentIdstringEnvironment that contains the service.
deploymentIdstringIdentifier to use when reading deployment history or logs.
Errors
400Invalid parameters. Check the required fields, types, and resource configuration.
401The API key is missing, invalid, or revoked.
403The caller or key scope does not permit this operation.
409The current resource state prevents the operation. Inspect it before retrying.
500The operation could not be completed. Check resource state before retrying a write.
deploy_upload
Required MCP arguments: projectSlug, name, archiveBase64. Send path, query, and body fields together as tool arguments.