Billing profiles

Customer billing data, reused across orders: list, create, edit, pick a default, and delete. Paths are relative to the /api/v1 prefix; all routes require Authorization: Bearer {token}.

The address here is the billing address — plain text, no coordinates. It is unrelated to addresses, which are delivery addresses.

See Common errors.

Endpoints

Method URI Role Description
GET /billing-profiles any List the caller's billing profiles
POST /billing-profiles any Create a billing profile (max 5)
PUT /billing-profiles/{id} any Replace a billing profile
PUT /billing-profiles/{id}/default any Mark a profile as the default
DELETE /billing-profiles/{id} any Delete a billing profile

Every endpoint is scoped to the authenticated user; profiles owned by other users are never returned and resolve as NotFound.

entity_type is PERSONAL (natural person, name is the person's name) or JURIDICA (company, name is the razĂłn social).


GET /billing-profiles

Lists the caller's billing profiles, the default first (is_default desc) then oldest first (created_at asc).

Response 200

{
  "items": [
    {
      "id": 7,
      "user_id": 1,
      "entity_type": "JURIDICA",
      "id_number": "J-123456789",
      "name": "Distribuidora Aguas del Valle, C.A.",
      "address": "Av. Libertador, Torre Norte, Piso 3, Caracas",
      "phone": "+58 212 5551234",
      "is_default": true,
      "created_at": "2026-08-15T12:00:00.000000Z",
      "updated_at": "2026-08-15T12:00:00.000000Z"
    }
  ]
}

items is an empty array when the user has no billing profiles.


POST /billing-profiles

Creates a billing profile for the caller. A user may keep at most 5. When isDefault is true, any previous default is cleared. The first profile a user creates is stored as the default even when isDefault is omitted.

Request body

Field Type Required Rules
entityType string yes PERSONAL or JURIDICA
idNumber string yes max 20 chars. V- / E- + 6–9 digits when PERSONAL; J- / G- + 8–10 digits when JURIDICA
name string yes 3–160 chars
address string yes 3–280 chars
phone string yes max 20 chars
isDefault boolean no defaults to false

idNumber is normalized before validation: case, spaces, dots and a missing dash are fixed, so v12345678 and V-12.345.678 are both stored as V-12345678.

Response 201 — { "billing_profile": { … } } (the created profile, same shape as an items entry).

Errors

Status Body When
422 { "error": "ValidationError", "details": { "fieldErrors": { … } } } A field is missing, or idNumber does not match the shape required by entityType
409 { "error": "TooMany", "message": "Máximo 5 datos de facturación." } The user already has 5 profiles

PUT /billing-profiles/{id}

Replaces the profile: every field of POST is required. Sending isDefault: true also promotes it; a profile that is already the default stays the default.

Response 200 — { "billing_profile": { … } } (the updated profile).

Errors

Status Body When
422 { "error": "ValidationError", "details": { "fieldErrors": { … } } } A field is missing, or idNumber does not match entityType
404 { "error": "NotFound" } Unknown profile, or it belongs to another user

PUT /billing-profiles/{id}/default

Marks the given profile as the caller's default, clearing the previous default.

Response 200 — { "billing_profile": { … } } (now is_default: true).

Errors

Status Body When
404 { "error": "NotFound" } Unknown profile, or it belongs to another user

DELETE /billing-profiles/{id}

Deletes one of the caller's billing profiles. Deleting the default promotes the oldest remaining profile.

Response 204 No Content.

Errors

Status Body When
404 { "error": "NotFound" } Unknown profile, or it belongs to another user

Examples

# Create a company billing profile
curl -X POST /api/v1/billing-profiles \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"entityType": "JURIDICA", "idNumber": "J-123456789", "name": "Distribuidora Aguas del Valle, C.A.", "address": "Av. Libertador, Torre Norte, Piso 3, Caracas", "phone": "+58 212 5551234", "isDefault": true}'

# Switch the default to another profile
curl -X PUT /api/v1/billing-profiles/7/default -H "Authorization: Bearer {token}"