Project billing
These routes show how much a project consumed: the usage computed hour by hour (projects with hourly billing) and the billing entries associated with the project. To understand the payment models, see Payments and billing.
Authentication and permissions
The routes accept an organization API Key (x-api-key: znf_... or Authorization: Bearer znf_...) or a user token with x-organization-id. Both require project.billing.read on project:<project-id> (or project:*). project.metrics.read does not grant access to financial values. owner has full access.
| Route | Limit |
|---|---|
GET /v1/project/:id/billing/hourly-usage | 50 per minute |
GET /v1/project/:id/billing/ledger | 50 per minute |
Monetary values are numbers in BRL cents and can be fractional (up to 8 decimal places). Divide by 100 to display them in reais.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
from | ISO 8601 string | — | Period start (inclusive) |
to | ISO 8601 string | — | Period end (exclusive) |
page | integer | 1 | Page, starting at 1 |
limit | integer | 10 | Items per page, from 1 to 50 |
status | string | — | Ledger only: pending or applied |
Values outside these formats return 400. A project that does not exist in the organization returns 404 with Project not found.
Hourly usage
GET /v1/project/:id/billing/hourly-usage?from=2026-10-01T00:00:00Z&to=2026-10-08T00:00:00Z{
"status": "success",
"message": "get project hourly usage with success",
"data": {
"hours": [
{
"id": "6702a1b2c3d4e5f6a7b8c9d0",
"hour_start": "2026-10-07T23:00:00.000Z",
"hour_end": "2026-10-08T00:00:00.000Z",
"currency": "brl",
"compute_amount": 12.5,
"storage_amount": 0.4,
"total_amount": 12.9,
"compute_instance_hours": 1,
"storage_gb_hours": 10,
"status": "charged",
"calculated_at": "2026-10-08T00:05:00.000Z",
"charged_at": "2026-10-08T00:10:00.000Z"
}
],
"summary": {
"currency": "brl",
"compute_amount": 12.5,
"storage_amount": 0.4,
"total_amount": 12.9
},
"pagination": { "page": 1, "limit": 10, "total": 1, "total_pages": 1 }
}
}| Field | Description |
|---|---|
hours[] | One entry per computed hour, from newest to oldest. The period filter uses hour_start |
compute_amount / storage_amount / total_amount | Capacity, storage, and total amount for the hour |
compute_instance_hours | Instance-hours considered for the hour |
storage_gb_hours | Storage GB-hours considered for the hour |
status | pending (computed, not charged yet) or charged |
charged_at | When the charge happened, if it already did |
summary | Sum of the whole filtered period, not only the page |
Projects with a monthly or yearly contract and scheduled Jobs (billed per minute) have no hourly usage: the route returns 200 with empty hours, 0 totals, and total: 0. The cost of Job runs is in Scheduled Jobs.
Billing entries
GET /v1/project/:id/billing/ledger?status=pending{
"status": "success",
"message": "get project billing ledger with success",
"data": {
"entries": [
{
"id": "6702a1b2c3d4e5f6a7b8c9d1",
"category": "usage",
"description": "Uso computado",
"amount": 12.5,
"currency": "brl",
"status": "pending",
"occurred_at": "2026-10-08T00:05:00.000Z"
}
],
"summary": {
"currency": "brl",
"adjustment_amount": 0,
"storage_amount": 0,
"usage_amount": 12.5,
"total_amount": 12.5
},
"summary_by_currency": [
{
"currency": "brl",
"adjustment_amount": 0,
"storage_amount": 0,
"usage_amount": 12.5,
"total_amount": 12.5
}
],
"pagination": { "page": 1, "limit": 10, "total": 1, "total_pages": 1 }
}
}| Field | Description |
|---|---|
category | usage (capacity or database usage), storage, or adjustment (balance adjustment) |
description | Descriptive text for the entry, in Portuguese |
status | pending (waiting to be applied) or applied (already applied to the balance) |
occurred_at | When the entry was recorded; the period filter uses this field |
applied_at | When the entry was applied, if it already was |
summary | Totals by category for the whole filtered period. Absent when there is more than one currency; in that case, use summary_by_currency |
Entries are sorted from newest to oldest.
Example
curl "https://api.zenifra.com/v1/project/6650f1a2b3c4d5e6f7a8b9c0/billing/hourly-usage?page=1&limit=24" \
-H "x-api-key: znf_..."Next steps
- Check current prices in the catalogs of Create, list, and delete projects.
- See Job costs in Scheduled Jobs and preview costs in Preview environments.
- Understand the billing models in Payments and billing.
Last updated on
Application network access
Restrict through the API which IP ranges can reach a public HTTP application, using allow and block lists in IPv4 CIDR notation with per-list limits.
Scheduled Jobs API
Create Scheduled Jobs, update cron schedules, and read runs, logs, and metrics with the Zenifra REST API and per-minute BRL billing.