Project information

This reference covers paginated project listing and reading or updating a specific project.

Authentication and permissions

Send an authorized session or organization API Key together with the organization context. The list contains only projects the credential may read. Reading one project requires project.read on project:<project-id>. For updates on this page, also use project.name.update, project.description.update, or project.domain.update, depending on the operation.

List projects

GET /v1/project

Query parameters

ParameterTypeDefaultDescription
pageinteger1List page; must be at least 1
limitinteger15Items per page, from 1 to 50
typestring—http, postgresql, mariadb, valkey, clickhouse, or job
profilestring—Valkey profile: key_value, cache, or queue; accepted only with type=valkey
statusstring—creating, running, resuming, stopped, downloading, failed, failing, or deploying
searchstring—Search by name or description (1 to 256 characters)
sort_bystringupdated_atupdated_at or created_at
sort_orderstringdescasc or desc

Filters can be combined. To list only Valkey caches, for example:

curl "https://api.zenifra.com/v1/project?type=valkey&profile=cache&page=1&limit=15" \
  -H "x-api-key: <organization-api-key>" \
  -H "x-organization-id: <organization-id>"

Reduced response

{
  "status": "success",
  "message": "get projects with success",
  "data": {
    "projects": [
      {
        "id": "<project-id>",
        "name": "api-cache",
        "type_project": "valkey",
        "plan": "cache-free",
        "status": "running",
        "managed_service": { "profile": "cache" }
      }
    ],
    "pagination": { "page": 1, "limit": 15, "total": 1, "pages": 1 }
  }
}

Rate limit: 100 requests per minute.

The API returns 400 when profile is not key_value, cache, or queue, or when it is sent without type=valkey.

Get project information

Returns the current project state, including status, plan, domain, instances, storage, port, public deployment settings, and type-specific additional information.

GET /v1/project/:id

Rate limit: 100 requests per minute (counted per source IP).

Path Parameters

ParameterTypeDescription
idstringProject ID

Headers

HeaderRequiredDescription
x-api-key or AuthorizationYesOrganization API Key or user token
x-organization-idWith a user tokenActive project organization. Not needed with an organization API key
Content-Type: application/jsonConditionalRequired only for PATCH calls

Response

The example below is reduced to highlight the most commonly used fields. The response may also include fields such as github, image, last_deployment, renew_automatic_contract, custom_domains, network_access, build_failure, updated_at, and created_at.

For HTTP projects, exposure indicates whether the application has a public route (public) or runs without a public domain (private). Private projects may return an empty or absent domain.

{
  "status": "success",
  "message": "get deployment with success",
  "data": {
    "name": "my-project",
    "description": "My web application",
    "domain": "my-project.clients.zenifra.com",
    "plan": "basic",
    "status": "running",
    "type_project": "http",
    "exposure": "public",
    "instances": 2,
    "storage": {
      "persistent": false,
      "capacity": 1
    },
    "payment_mode": "hourly",
    "port": 3000,
    "additional_info": {
      "current_instances": 2,
      "max_cpu": "500m",
      "max_memory": "512Mi"
    }
  }
}

Plan change on Analytics projects

On Analytics projects, GET /v1/project/:id includes plan_change while a plan change is running (in_progress) or after a change that could not be completed (failed). The failed state stays present until the next plan change is accepted, which clears it. The field is absent only when no change is running and no previous failure is recorded.

{ "plan_change": { "status": "in_progress", "to_plan": "analytics-starter", "started_at": "2026-10-11T12:00:00.000Z" } }
{ "plan_change": { "status": "failed", "from_plan": "analytics-production", "to_plan": "analytics-starter", "finished_at": "2026-10-11T12:08:00.000Z" } }

in_progress means the change continues in the background; check again in a few minutes. failed means the change could not be completed and the project stays on the previous plan (from_plan). See Change plan for the 202 and errors of PATCH /v1/project/:id/plan.


Update Project Exposure

Changes whether an HTTP project exposes a public route.

PATCH /v1/project/:id/exposure

Accepts a user session or an organization API Key. Requires project.domain.update.

Body

FieldTypeRequiredDescription
exposurestringYesUse public to create a public route/domain or private to remove public exposure
{
  "exposure": "private"
}

Private projects do not receive a Zenifra subdomain and cannot configure a public domain while they remain private. Only HTTP projects accept this operation.

Response

{
  "status": "success",
  "message": "project exposure updated with success",
  "exposure": "private",
  "domain": "",
  "custom_domains": []
}

When changing to private, the API removes the public route, default subdomain, and custom domains. When changing to public, the API provisions the public route again and returns the available domain.

Errors

StatusWhen it happens
400The project is a database (cant change database exposure)
404Project not found
409An exposure change is already in progress for the project, or the requested domain is not available
503A public address could not be assigned right now; try again shortly

Rate limit: 5 requests every 5 minutes.


Update Project Name

Changes the project name.

PATCH /v1/project/:id/name

Rate limit: 10 requests per minute (counted per source IP).

Path Parameters

ParameterTypeDescription
idstringProject ID

Body

FieldTypeRequiredDescription
namestringYesNew project name (minimum 6 characters, maximum 32, lowercase letters and numbers only, hyphens allowed)

Example

{
  "name": "my-new-project"
}

Response

{
  "status": "success",
  "message": "updated with success"
}

Update Project Description

Changes the project description.

PATCH /v1/project/:id/description

Rate limit: 10 requests per minute (counted per source IP).

Path Parameters

ParameterTypeDescription
idstringProject ID

Body

FieldTypeRequiredDescription
descriptionstringNoNew project description (1 to 256 characters)

Response

{
  "status": "success",
  "message": "updated with success"
}

Examples

Update Name

curl -X PATCH "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011/name" \
  -H "x-api-key: your-api-key" \
  -H "x-organization-id: your-organization-id" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-new-project"}'

Update Description

curl -X PATCH "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011/description" \
  -H "x-api-key: your-api-key" \
  -H "x-organization-id: your-organization-id" \
  -H "Content-Type: application/json" \
  -d '{"description": "My web application in production"}'

Python

import requests

API_KEY = "your-api-key"
ORGANIZATION_ID = "your-organization-id"
PROJECT_ID = "507f1f77bcf86cd799439011"

headers = {"x-api-key": API_KEY, "x-organization-id": ORGANIZATION_ID}

# Get information
project = requests.get(
    f"https://api.zenifra.com/v1/project/{PROJECT_ID}",
    headers=headers
).json()
print(project)

# Update name
requests.patch(
    f"https://api.zenifra.com/v1/project/{PROJECT_ID}/name",
    headers=headers,
    json={"name": "my-new-project"}
)

# Update description
requests.patch(
    f"https://api.zenifra.com/v1/project/{PROJECT_ID}/description",
    headers=headers,
    json={"description": "My web application in production"}
)

Last updated on

On this page