API Reference
Usage

Usage API

The Usage API exposes project event totals, project daily event counts, and current organization-level event usage.

The current public routes are:

GET /v1/usage
GET /v1/usage/current
GET /v1/projects/{project_id}/usage/daily

These endpoints answer different questions:

EndpointScopePrimary result
GET /v1/usageProjectEvent totals grouped by event name for a selected period
GET /v1/projects/{project_id}/usage/dailyProjectEvent counts grouped by calendar date
GET /v1/usage/currentOrganization containing the API-key projectCurrent UTC-month event usage and an explicitly configured monthly limit

Authentication

The endpoints use two authentication models.

EndpointAuthenticationRequired access
GET /v1/usageBearer access tokenMembership in the selected project’s organization
GET /v1/projects/{project_id}/usage/dailyBearer access tokenMembership in the selected project’s organization
GET /v1/usage/currentX-API-KeyAPI key with events:read

Bearer header:

Authorization: Bearer YOUR_ACCESS_TOKEN

API-key header:

X-API-Key: YOUR_API_KEY

OpenAPI discrepancy for current usage

The current OpenAPI snapshot shows the X-API-Key header as optional and does not attach an explicit security requirement to GET /v1/usage/current.

The runtime dependency requires an API key with the events:read scope. Client implementations must follow the runtime authentication requirement.

Project usage summary

GET /v1/usage

This endpoint counts project events inside a selected time period and groups them by event name.

Query parameters

ParameterTypeRequiredDefaultConstraints
project_idUUIDYesAccessible project
periodStringNo30d24h, 7d, 30d, or month

Period semantics

ValueTime window
24hRolling previous 24 hours
7dRolling previous 7 days
30dRolling previous 30 days
monthStart of the current UTC month through the start of the next UTC month

The query uses an inclusive lower bound and an exclusive upper bound:

event_time >= from_ts
event_time < to_ts

For month, to_ts is the first instant of the following month rather than the current request time.

Example request

curl --silent --show-error   --get   "${LARIBA_API_BASE_URL}/v1/usage"   --header "Authorization: Bearer $LARIBA_ACCESS_TOKEN"   --data-urlencode "project_id=$LARIBA_PROJECT_ID"   --data-urlencode "period=30d"

Response

{
  "project_id": "PROJECT_UUID",
  "project_name": "Checkout Production",
  "period": "30d",
  "from_ts": "2026-06-24T20:00:00+00:00",
  "to_ts": "2026-07-24T20:00:00+00:00",
  "total_events": 1420,
  "by_event": [
    {
      "event": "order.completed",
      "total": 920
    },
    {
      "event": "payment.failed",
      "total": 500
    }
  ]
}

Response fields

FieldTypeDescription
project_idStringSelected project identifier
project_nameStringSelected project name
periodStringApplied period
from_tsStringInclusive UTC lower bound
to_tsStringExclusive UTC upper bound
total_eventsIntegerSum of all grouped event totals
by_eventArrayEvent names and their counts

The by_event array is ordered by count in descending order.

The endpoint does not currently return pagination metadata because it returns grouped aggregate rows rather than individual events.

Event-column fallbacks

The runtime resolves the event time column using:

timestamp
created_at

It resolves the event-name column using:

event
type

The first available field is used. A missing time or event-name column produces an internal server error rather than an incomplete result.

Project daily usage

GET /v1/projects/{project_id}/usage/daily

This endpoint groups project events by database calendar date.

Path parameter

ParameterTypeRequired
project_idUUIDYes

Query parameter

ParameterTypeRequiredDefaultConstraints
daysIntegerNo30Minimum 1, maximum 365

Example request

curl --silent --show-error   --get   "${LARIBA_API_BASE_URL}/v1/projects/${LARIBA_PROJECT_ID}/usage/daily"   --header "Authorization: Bearer $LARIBA_ACCESS_TOKEN"   --data-urlencode "days=30"

Response

{
  "project_id": "PROJECT_UUID",
  "usage": [
    {
      "date": "2026-07-22",
      "events": 84
    },
    {
      "date": "2026-07-23",
      "events": 102
    },
    {
      "date": "2026-07-24",
      "events": 61
    }
  ]
}

Daily-result behaviour

The runtime:

  1. calculates a rolling lower bound from the current UTC time minus days;
  2. filters events for the selected project;
  3. groups matching rows by calendar date;
  4. orders dates in ascending order;
  5. returns only dates represented by matching event rows.

The response does not currently zero-fill dates that have no events.

The endpoint resolves the event time column by preferring timestamp and falling back to created_at.

Current organization usage

GET /v1/usage/current

This endpoint is intended for machine integrations that need current-month event usage.

It derives the organization from the project attached to the authenticated API key.

Required scope

The API key must include:

events:read

Example request

curl --silent --show-error   --request GET   "${LARIBA_API_BASE_URL}/v1/usage/current"   --header "X-API-Key: $LARIBA_API_KEY"

Response

{
  "organization_id": "ORGANIZATION_UUID",
  "month": "2026-07",
  "from_day": "2026-07-01",
  "to_day": "2026-08-01",
  "reset_day": "2026-08-01",
  "events_used": 8240,
  "events_limit": 10000,
  "events_remaining": 1760
}

Response fields

FieldTypeDescription
organization_idStringOrganization containing the authenticated API-key project
monthStringCurrent UTC month in YYYY-MM format
from_dayStringFirst day of the current UTC month
to_dayStringFirst day of the following UTC month
reset_dayStringCurrent usage reset boundary
events_usedIntegerSum of metered events across organization projects for the current month
events_limitInteger or nullExplicit events_per_month_limit value stored on the organization
events_remainingInteger or nullNon-negative difference between the explicit limit and usage

The current-month query includes usage rows where:

day >= from_day
day < to_day

Usage is aggregated across every project belonging to the organization, not only the project associated with the requesting API key.

Null-limit semantics

When the organization does not have an explicit events_per_month_limit value:

{
  "events_limit": null,
  "events_remaining": null
}

A null value in this response does not by itself prove that the organization has an unlimited commercial plan.

The billing layer can resolve effective limits from plan defaults or organization overrides. The current usage endpoint reads only the organization’s explicit events_per_month_limit field and does not call the effective plan-limit resolver.

Clients should use billing status and enforcement responses when they need authoritative commercial quota information.

Usage storage model

Daily metering is stored in usage_daily.

Its composite identity includes:

day
project_id
api_key_id

The model records:

FieldTypePurpose
dayDateUTC usage day
project_idUUIDProject scope
api_key_idUUID or nullAPI-key scope where available
requestsIntegerMetered successful API-key requests
events_ingestedIntegerMetered ingested events
updated_atDate-timeLast update time

GET /v1/usage/current reads events_ingested. It does not return the stored requests counter.

GET /v1/usage and the project daily endpoint query event records directly rather than reading aggregate rows from usage_daily.

Request-metering behaviour

The usage-metering middleware tracks API-key request usage.

A request is eligible for a request increment when:

  1. usage metering is enabled;
  2. the request supplies X-API-Key;
  3. the key resolves to an API-key record;
  4. the response status is below 400;
  5. the request was not already metered by another path.

The request increment happens after the successful response has been produced.

Requests without X-API-Key are not counted by this middleware. This includes ordinary Bearer-authenticated dashboard requests.

Bypassed paths

The middleware bypasses:

/v1/stripe/webhook
/health
/docs
/redoc
/openapi.json

Failure tolerance

When usage tables are missing in a transitional database state, the middleware is designed not to break the underlying API request.

This fail-open behaviour applies to metering availability. It does not disable authentication, authorization, billing enforcement, or ingestion quota checks.

Reporting versus enforcement

Usage reporting and quota enforcement are related but separate concerns.

Reporting

The endpoints in this reference return:

  • event aggregates from event records;
  • daily event counts from event records;
  • current-month metered event totals from usage_daily.

Enforcement

Ingestion enforcement can reject requests based on:

  • billing state;
  • monthly event quota;
  • monthly request quota;
  • plan or organization configuration.

Quota enforcement can return HTTP 403 with operational headers such as:

X-Lariba-Block-Reason
X-Lariba-Monthly-Limit
X-Lariba-Monthly-Used
X-Lariba-Monthly-Request-Limit
X-Lariba-Monthly-Requests-Used
X-Lariba-Period-Start
X-Lariba-Period-End
X-Lariba-Upgrade-URL

Do not interpret an HTTP 403 quota gate as the HTTP 429 sliding-window rate limit.

Rate limits

The named usage sliding-window policy matches:

GET /v1/usage
GET /v1/usage/current

Its current defaults are:

WindowIP limitCredential limitBucket scope
60 seconds1020Credential, with IP fallback

Relevant headers include:

X-RateLimit-Policy
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
Retry-After

A blocked request returns:

{
  "detail": "Rate limit exceeded"
}

The named usage rule matches the /v1/usage prefix. The project daily route is under /v1/projects, so it is outside that specific prefix rule.

This does not guarantee that the daily route can never be protected by another runtime control.

Errors

The OpenAPI snapshot explicitly lists successful 200 and validation 422 responses. Runtime authentication, authorization, quota, rate-limit, and integrity checks can produce additional statuses.

StatusTypical meaning
400The API-key project has no organization
401Missing, invalid, expired, or insufficiently scoped authentication
403User lacks authoritative project access or a quota gate blocks an operation
404Project or organization was not found
422Invalid UUID, unsupported period, or invalid days constraint
429Named Usage API rate limit exceeded
500Required event time or event-name column is unavailable

Unsupported project usage period:

{
  "detail": "period must be one of: 24h, 7d, 30d, month"
}

Missing organization on the API-key project:

{
  "detail": "Project has no organization"
}

Missing organization record:

{
  "detail": "Organization not found"
}

Validation failures can use FastAPI’s validation-array response rather than a string detail.

Client guidance

  1. use Bearer authentication for project reporting endpoints;
  2. use an API key with events:read for current machine usage;
  3. treat the runtime requirement as authoritative where OpenAPI security metadata is incomplete;
  4. use month only when calendar-month semantics are required;
  5. remember that 30d is a rolling window, not the current calendar month;
  6. do not assume the daily response includes zero-event dates;
  7. do not infer unlimited usage from a null events_limit;
  8. distinguish event-record aggregates from usage_daily metering totals;
  9. distinguish HTTP 403 quota enforcement from HTTP 429 rate limiting;
  10. never log plaintext API keys.

Related documentation