Skip to content
Klozzo API
OpenAPI Postman

Reference

Negocios y Cotizaciones

The customer as a legal entity (D2): the thing a quote is actually addressed to, with its RFC and its fiscal details. Not to be confused with the CompanyProfile, which is the CRM owner's own branding.

external_ref is the bridge to your system — set it once and every later call can find the company by your identifier instead of ours.

List companies

Lists the companies of the location the API token belongs to.

GET /api/v1/companies

Query parameters

  • search string

    Free text over name, legal name and RFC.

    Example: ADPA

  • external_ref string

    Find the one carrying your identifier.

    Example: verificamex-99

  • per_page integer

    Rows per page. Default 50, maximum 100. See Lists, paging and filters.

    Example: 50

curl --request GET \
    --get "https://klozzo.com/api/v1/companies?search=ADPA&external_ref=verificamex-99&per_page=50" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": [
        {
            "id": null,
            "ulid": null,
            "name": "Price Ltd",
            "legal_name": null,
            "tax_id": null,
            "tax_regime": null,
            "cfdi_use": null,
            "address": null,
            "email": "contacto@cronin.example",
            "phone": null,
            "website": null,
            "industry": null,
            "owner_id": null,
            "external_ref": null,
            "notes": null,
            "created_at": null,
            "updated_at": null
        },
        {
            "id": null,
            "ulid": null,
            "name": "Hauck-Leuschke",
            "legal_name": null,
            "tax_id": null,
            "tax_regime": null,
            "cfdi_use": null,
            "address": null,
            "email": "contacto@baumbach.example",
            "phone": null,
            "website": null,
            "industry": null,
            "owner_id": null,
            "external_ref": null,
            "notes": null,
            "created_at": null,
            "updated_at": null
        }
    ]
}
  • data object[]

    • id string

    • ulid string

    • name string

    • legal_name string

    • tax_id string

    • tax_regime string

    • cfdi_use string

    • address string

    • email string

    • phone string

    • website string

    • industry string

    • owner_id string

    • external_ref string

    • notes string

    • created_at string

    • updated_at string

Create a company

Creates a company in this location. A company is the fiscal counterpart of a deal: who the invoice is made out to. Create it when you are about to quote somebody who buys as a business, not for every contact — a person who buys as a person needs no company.

POST /api/v1/companies

Put your own identifier in external_ref and you never have to store ours. It is unique inside the location, so a retry that sends the same one gets a 422 rather than a second row.

Body parameters

  • name string required

    Trading name.

    Example: ADPA

  • legal_name string

    Razón social.

    Example: ADPA, S.A. de C.V.

  • tax_id string

    RFC. Unique inside the location.

    Example: ADP010101AB1

  • tax_regime string

    SAT regime code.

    Example: 601

  • cfdi_use string

    SAT CFDI use code.

    Example: G03

  • email string

    Example: contacto@example.com

  • phone string

    The company switchboard. Free text: unlike a contact's phone this one is neither validated nor normalised, so send E.164 if you intend to dial it.

    Example: +525555555555

  • external_ref string

    Your identifier for this company. Unique inside the location.

    Example: verificamex-99

curl --request POST \
    "https://klozzo.com/api/v1/companies" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"ADPA\",
    \"legal_name\": \"ADPA, S.A. de C.V.\",
    \"tax_id\": \"ADP010101AB1\",
    \"tax_regime\": \"601\",
    \"cfdi_use\": \"G03\",
    \"email\": \"contacto@example.com\",
    \"phone\": \"+525555555555\",
    \"external_ref\": \"verificamex-99\"
}"
{
    "data": {
        "id": null,
        "ulid": null,
        "name": "Price Ltd",
        "legal_name": null,
        "tax_id": null,
        "tax_regime": null,
        "cfdi_use": null,
        "address": null,
        "email": "contacto@dare.example",
        "phone": null,
        "website": null,
        "industry": null,
        "owner_id": null,
        "external_ref": null,
        "notes": null,
        "created_at": null,
        "updated_at": null
    }
}
  • data object

    • id string

    • ulid string

    • name string

    • legal_name string

    • tax_id string

    • tax_regime string

    • cfdi_use string

    • address string

    • email string

    • phone string

    • website string

    • industry string

    • owner_id string

    • external_ref string

    • notes string

    • created_at string

    • updated_at string

Fetch a company

Returns one company by its ULID, with everything on file plus contacts_count and deals_count, which is usually what you actually wanted: whether this company is worth a call.

GET /api/v1/companies/{ulid}

A company from another location answers 404, never 403 — telling an outsider "that exists but is not yours" is telling them it exists.

Path parameters

  • ulid string required

    Company ULID (a numeric id still resolves).

    Example: 01JZ8Z0ZP0000000000000000

curl --request GET \
    --get "https://klozzo.com/api/v1/companies/01JZ8Z0ZP0000000000000000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": {
        "id": null,
        "ulid": null,
        "name": "Price Ltd",
        "legal_name": null,
        "tax_id": null,
        "tax_regime": null,
        "cfdi_use": null,
        "address": null,
        "email": "contacto@hauck.example",
        "phone": null,
        "website": null,
        "industry": null,
        "owner_id": null,
        "external_ref": null,
        "notes": null,
        "created_at": null,
        "updated_at": null
    }
}
  • data object

    • id string

    • ulid string

    • name string

    • legal_name string

    • tax_id string

    • tax_regime string

    • cfdi_use string

    • address string

    • email string

    • phone string

    • website string

    • industry string

    • owner_id string

    • external_ref string

    • notes string

    • created_at string

    • updated_at string

Update a company

Updates a company by its ULID, changing only the fields you send. Fields you leave out are left alone, so this is safe to call from a sync that only knows about the tax data.

PUT /api/v1/companies/{ulid}

Use it to fill in fiscal details a seller could not collect at the time — an RFC that arrives with the purchase order, a CFDI use the accountant corrects. Changing name here does not rename anything else: deals and quotes already issued keep the name they were issued with.

Path parameters

  • ulid string required

    Company ULID (a numeric id still resolves).

    Example: 01JZ8Z0ZP0000000000000000

curl --request PUT \
    "https://klozzo.com/api/v1/companies/01JZ8Z0ZP0000000000000000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": {
        "id": null,
        "ulid": null,
        "name": "Price Ltd",
        "legal_name": null,
        "tax_id": null,
        "tax_regime": null,
        "cfdi_use": null,
        "address": null,
        "email": "contacto@leuschke.example",
        "phone": null,
        "website": null,
        "industry": null,
        "owner_id": null,
        "external_ref": null,
        "notes": null,
        "created_at": null,
        "updated_at": null
    }
}
  • data object

    • id string

    • ulid string

    • name string

    • legal_name string

    • tax_id string

    • tax_regime string

    • cfdi_use string

    • address string

    • email string

    • phone string

    • website string

    • industry string

    • owner_id string

    • external_ref string

    • notes string

    • created_at string

    • updated_at string

List deals

Lists the deals of this location, newest first. Use it to reconcile: ask for ?external_ref= to find the one carrying your identifier, or for ?status=open to see what is still in play before you close something on your side.

GET /api/v1/deals

What you see depends on the token. A token belonging to somebody who manages the location sees every deal; a seller's token sees only their own. That is not a filter you can turn off, so a partial list is not a bug — it is whose token you are using.

Query parameters

  • status string

    One of open, won, lost.

    Example: open

  • company_id integer

    Only this company's deals.

    Example: 12

  • external_ref string

    Find the one carrying your identifier.

    Example: sub_88213

  • per_page integer

    Rows per page. Default 50, maximum 100. See Lists, paging and filters.

    Example: 50

curl --request GET \
    --get "https://klozzo.com/api/v1/deals?status=open&company_id=12&external_ref=sub_88213&per_page=50" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": [
        {
            "id": 1,
            "ulid": "01KYDKV7N1RMWVK8H79M9H20V1",
            "title": "ADPA — Paquete 1,100 firmas",
            "description": null,
            "status": "open",
            "status_label": "Abierto",
            "amount": {
                "amount": 250140000,
                "currency": "MXN",
                "decimal": "25014.0000",
                "formatted": "$25,014.00"
            },
            "paid": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "balance": {
                "amount": 250140000,
                "currency": "MXN",
                "decimal": "25014.0000",
                "formatted": "$25,014.00"
            },
            "weighted_amount": {
                "amount": 100056000,
                "currency": "MXN",
                "decimal": "10005.6000",
                "formatted": "$10,005.60"
            },
            "currency": "MXN",
            "pipeline_id": 1,
            "pipeline_stage_id": 2,
            "stage": {
                "id": 2,
                "name": "Cotización enviada",
                "probability": 40,
                "is_won": false,
                "is_lost": false
            },
            "company_id": 1,
            "primary_contact_id": null,
            "owner_id": 26,
            "expected_close_date": null,
            "closed_at": null,
            "lost_reason": null,
            "source": null,
            "attribution": null,
            "external_ref": null,
            "created_at": "2026-07-25T03:58:03+00:00",
            "updated_at": "2026-07-25T03:58:03+00:00"
        },
        {
            "id": 1,
            "ulid": "01KYDKV7N1RMWVK8H79M9H20V1",
            "title": "ADPA — Paquete 1,100 firmas",
            "description": null,
            "status": "open",
            "status_label": "Abierto",
            "amount": {
                "amount": 250140000,
                "currency": "MXN",
                "decimal": "25014.0000",
                "formatted": "$25,014.00"
            },
            "paid": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "balance": {
                "amount": 250140000,
                "currency": "MXN",
                "decimal": "25014.0000",
                "formatted": "$25,014.00"
            },
            "weighted_amount": {
                "amount": 100056000,
                "currency": "MXN",
                "decimal": "10005.6000",
                "formatted": "$10,005.60"
            },
            "currency": "MXN",
            "pipeline_id": 1,
            "pipeline_stage_id": 2,
            "stage": {
                "id": 2,
                "name": "Cotización enviada",
                "probability": 40,
                "is_won": false,
                "is_lost": false
            },
            "company_id": 1,
            "primary_contact_id": null,
            "owner_id": 26,
            "expected_close_date": null,
            "closed_at": null,
            "lost_reason": null,
            "source": null,
            "attribution": null,
            "external_ref": null,
            "created_at": "2026-07-25T03:58:03+00:00",
            "updated_at": "2026-07-25T03:58:03+00:00"
        }
    ]
}
  • data object[]

    • id integer

    • ulid string

    • title string

    • description string

    • status string

    • status_label string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • paid object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • balance object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • weighted_amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • pipeline_id integer

    • pipeline_stage_id integer

    • stage object

      • id integer

      • name string

      • probability integer

      • is_won boolean

      • is_lost boolean

    • company_id integer

    • primary_contact_id string

    • owner_id integer

    • expected_close_date string

    • closed_at string

    • lost_reason string

    • source string

    • attribution string

    • external_ref string

    • created_at string

    • updated_at string

Create a deal

Creates a deal — an opportunity — in the location's default pipeline unless another is named. The attribution of its contact is frozen onto it at this moment and never recalculated (D17).

POST /api/v1/deals

Body parameters

  • title string required

    What is being sold.

    Example: ADPA — Paquete 1,100 firmas

  • description string

    Must not be greater than 5000 characters.

    Example: Et animi quos velit et fugiat.

  • company_id integer

    The customer company.

    Example: 12

  • primary_contact_id integer

    The person on the other end.

    Example: 340

  • owner_id integer

    The agent responsible. Defaults to the token's user.

    Example: 4

  • pipeline_id integer

    Defaults to the location's default pipeline.

    Example: 1

  • pipeline_stage_id string

  • expected_close_date string

    Example: 2026-08-30

  • source string

    Where it came from.

    Example: verificamex

  • external_ref string

    Your identifier for this deal. Unique inside the location.

    Example: sub_88213

curl --request POST \
    "https://klozzo.com/api/v1/deals" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"ADPA — Paquete 1,100 firmas\",
    \"description\": \"Et animi quos velit et fugiat.\",
    \"company_id\": 12,
    \"primary_contact_id\": 340,
    \"owner_id\": 4,
    \"pipeline_id\": 1,
    \"expected_close_date\": \"2026-08-30\",
    \"source\": \"verificamex\",
    \"external_ref\": \"sub_88213\"
}"
{
    "data": {
        "id": 1,
        "ulid": "01KYDKV7N1RMWVK8H79M9H20V1",
        "title": "ADPA — Paquete 1,100 firmas",
        "description": null,
        "status": "open",
        "status_label": "Abierto",
        "amount": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "paid": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "balance": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "weighted_amount": {
            "amount": 100056000,
            "currency": "MXN",
            "decimal": "10005.6000",
            "formatted": "$10,005.60"
        },
        "currency": "MXN",
        "pipeline_id": 1,
        "pipeline_stage_id": 2,
        "stage": {
            "id": 2,
            "name": "Cotización enviada",
            "probability": 40,
            "is_won": false,
            "is_lost": false
        },
        "company_id": 1,
        "primary_contact_id": null,
        "owner_id": 26,
        "expected_close_date": null,
        "closed_at": null,
        "lost_reason": null,
        "source": null,
        "attribution": null,
        "external_ref": null,
        "created_at": "2026-07-25T03:58:03+00:00",
        "updated_at": "2026-07-25T03:58:03+00:00"
    }
}
  • data object

    • id integer

    • ulid string

    • title string

    • description string

    • status string

    • status_label string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • paid object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • balance object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • weighted_amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • pipeline_id integer

    • pipeline_stage_id integer

    • stage object

      • id integer

      • name string

      • probability integer

      • is_won boolean

      • is_lost boolean

    • company_id integer

    • primary_contact_id string

    • owner_id integer

    • expected_close_date string

    • closed_at string

    • lost_reason string

    • source string

    • attribution string

    • external_ref string

    • created_at string

    • updated_at string

Reconcile a deal

Finds the deal by your identifier and closes it. If you did not put an external_ref on the deal, the company's is used instead — provided that company has exactly one open deal, because guessing which of three deals a payment belongs to is not a guess anybody should make.

POST /api/v1/deals/reconcile

Body parameters

  • external_ref string required

    Your identifier for the deal, or for its company.

    Example: sub_88213

  • status string

    One of won or lost. Defaults to won.

    Example: won

  • lost_reason string

    Required when status is lost.

    Example: Se fue con la competencia

  • accepted_quote_ids integer[]

    Which live quotes the customer actually took (D26). Omitted means none of them did, which is a valid answer.

    Example: [15]

  • amount string

    Record a payment of this size at the same time.

    Example: 25013.94

  • paid_at string

    When the money arrived. Defaults to now.

    Example: 2026-08-02

  • reference string

    Bank or charge reference.

    Example: SPEI-8891

  • payment_external_ref string

    Your identifier for the payment.

    Example: charge_9912

curl --request POST \
    "https://klozzo.com/api/v1/deals/reconcile" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Idempotency-Key: required A unique value per operation. A retry with the same key returns the first answer instead of doing the work again. Example: rec-2026-08-02-88213" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"external_ref\": \"sub_88213\",
    \"status\": \"won\",
    \"lost_reason\": \"Se fue con la competencia\",
    \"accepted_quote_ids\": [
        15
    ],
    \"amount\": \"25013.94\",
    \"paid_at\": \"2026-08-02\",
    \"reference\": \"SPEI-8891\",
    \"payment_external_ref\": \"charge_9912\"
}"
{
    "data": {
        "status": "won"
    },
    "meta": {
        "reconciled": true,
        "payment_recorded": true
    }
}
  • data object

    • status string

  • meta object

    • reconciled boolean

    • payment_recorded boolean

Link a deal to your identifier

Attaches your own identifier to a deal that already exists — for the ones that predate the integration. One deal, one external_ref, unique inside the location.

POST /api/v1/deals/{deal_ulid}/external-ref

Path parameters

  • deal_ulid string required

    Deal ULID.

    Example: 01JZ8Z0ZP0000000000000000

Body parameters

  • external_ref string required

    Your identifier.

    Example: sub_88213

curl --request POST \
    "https://klozzo.com/api/v1/deals/01JZ8Z0ZP0000000000000000/external-ref" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Idempotency-Key: required A unique value per operation. Example: link-88213" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"external_ref\": \"sub_88213\"
}"
{
    "data": {
        "id": 1,
        "ulid": "01KYDKV7N1RMWVK8H79M9H20V1",
        "title": "ADPA — Paquete 1,100 firmas",
        "description": null,
        "status": "open",
        "status_label": "Abierto",
        "amount": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "paid": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "balance": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "weighted_amount": {
            "amount": 100056000,
            "currency": "MXN",
            "decimal": "10005.6000",
            "formatted": "$10,005.60"
        },
        "currency": "MXN",
        "pipeline_id": 1,
        "pipeline_stage_id": 2,
        "stage": {
            "id": 2,
            "name": "Cotización enviada",
            "probability": 40,
            "is_won": false,
            "is_lost": false
        },
        "company_id": 1,
        "primary_contact_id": null,
        "owner_id": 26,
        "expected_close_date": null,
        "closed_at": null,
        "lost_reason": null,
        "source": null,
        "attribution": null,
        "external_ref": null,
        "created_at": "2026-07-25T03:58:03+00:00",
        "updated_at": "2026-07-25T03:58:03+00:00"
    }
}
  • data object

    • id integer

    • ulid string

    • title string

    • description string

    • status string

    • status_label string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • paid object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • balance object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • weighted_amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • pipeline_id integer

    • pipeline_stage_id integer

    • stage object

      • id integer

      • name string

      • probability integer

      • is_won boolean

      • is_lost boolean

    • company_id integer

    • primary_contact_id string

    • owner_id integer

    • expected_close_date string

    • closed_at string

    • lost_reason string

    • source string

    • attribution string

    • external_ref string

    • created_at string

    • updated_at string

Fetch a deal

Returns one deal by its ULID, with its stage and its company. Read status before you act on it: a deal a person here already closed is never flipped by the API, and this is where you find out that happened.

GET /api/v1/deals/{ulid}

Path parameters

  • ulid string required

    Deal ULID (a numeric id still resolves).

    Example: 01JZ8Z0ZP0000000000000000

curl --request GET \
    --get "https://klozzo.com/api/v1/deals/01JZ8Z0ZP0000000000000000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": {
        "id": 1,
        "ulid": "01KYDKV7N1RMWVK8H79M9H20V1",
        "title": "ADPA — Paquete 1,100 firmas",
        "description": null,
        "status": "open",
        "status_label": "Abierto",
        "amount": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "paid": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "balance": {
            "amount": 250140000,
            "currency": "MXN",
            "decimal": "25014.0000",
            "formatted": "$25,014.00"
        },
        "weighted_amount": {
            "amount": 100056000,
            "currency": "MXN",
            "decimal": "10005.6000",
            "formatted": "$10,005.60"
        },
        "currency": "MXN",
        "pipeline_id": 1,
        "pipeline_stage_id": 2,
        "stage": {
            "id": 2,
            "name": "Cotización enviada",
            "probability": 40,
            "is_won": false,
            "is_lost": false
        },
        "company_id": 1,
        "primary_contact_id": null,
        "owner_id": 26,
        "expected_close_date": null,
        "closed_at": null,
        "lost_reason": null,
        "source": null,
        "attribution": null,
        "external_ref": null,
        "created_at": "2026-07-25T03:58:03+00:00",
        "updated_at": "2026-07-25T03:58:03+00:00"
    }
}
  • data object

    • id integer

    • ulid string

    • title string

    • description string

    • status string

    • status_label string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • paid object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • balance object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • weighted_amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • pipeline_id integer

    • pipeline_stage_id integer

    • stage object

      • id integer

      • name string

      • probability integer

      • is_won boolean

      • is_lost boolean

    • company_id integer

    • primary_contact_id string

    • owner_id integer

    • expected_close_date string

    • closed_at string

    • lost_reason string

    • source string

    • attribution string

    • external_ref string

    • created_at string

    • updated_at string

List quotes

Lists the quotes issued in this location, newest first. Filter by deal_id to see the options offered on one opportunity, or by folio to look up the code a customer read out on the phone — with or without its prefix and dash, because nobody dictates punctuation.

GET /api/v1/quotes

A draft has no folio yet: the code is assigned when the quote is shared, which is also the moment its contents are frozen.

Query parameters

  • deal_id integer

    Only this deal's quotes.

    Example: 7

  • status string

    One of draft, shared, viewed, accepted, rejected, withdrawn, expired, superseded.

    Example: shared

  • folio string

    The dictated code, with or without prefix or dash.

    Example: COT-7K3M9

  • per_page integer

    Rows per page. Default 50, maximum 100. See Lists, paging and filters.

    Example: 50

curl --request GET \
    --get "https://klozzo.com/api/v1/quotes?deal_id=7&status=shared&folio=COT-7K3M9&per_page=50" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": [
        {
            "id": 1,
            "ulid": "01KYDKV7P4RVYJZZ6JNAJ521YR",
            "deal_id": 15,
            "company_id": null,
            "contact_id": 6295,
            "owner_id": 26,
            "quote_template_id": null,
            "folio": null,
            "reference": "Borrador",
            "version": 1,
            "title": "Patito",
            "intro": null,
            "status": "draft",
            "status_label": "Borrador",
            "is_option": false,
            "currency": "MXN",
            "subtotal": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "discount_total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "tax_total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "valid_until": "2026-08-09",
            "shared_at": null,
            "decided_at": null,
            "snapshot_hash": null,
            "external_ref": null,
            "pdf_url": "http://klozzo.com/api/v1/quotes/01KYDKV7P4RVYJZZ6JNAJ521YR/pdf/signed?893456000&signature=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
            "created_at": "2026-07-25T18:11:14+00:00",
            "updated_at": "2026-07-25T18:11:14+00:00"
        },
        {
            "id": 1,
            "ulid": "01KYDKV7P4RVYJZZ6JNAJ521YR",
            "deal_id": 15,
            "company_id": null,
            "contact_id": 6295,
            "owner_id": 26,
            "quote_template_id": null,
            "folio": null,
            "reference": "Borrador",
            "version": 1,
            "title": "Patito",
            "intro": null,
            "status": "draft",
            "status_label": "Borrador",
            "is_option": false,
            "currency": "MXN",
            "subtotal": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "discount_total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "tax_total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "total": {
                "amount": 0,
                "currency": "MXN",
                "decimal": "0.0000",
                "formatted": "$0.00"
            },
            "valid_until": "2026-08-09",
            "shared_at": null,
            "decided_at": null,
            "snapshot_hash": null,
            "external_ref": null,
            "pdf_url": "http://klozzo.com/api/v1/quotes/01KYDKV7P4RVYJZZ6JNAJ521YR/pdf/signed?893456000&signature=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
            "created_at": "2026-07-25T18:11:14+00:00",
            "updated_at": "2026-07-25T18:11:14+00:00"
        }
    ]
}
  • data object[]

    • id integer

    • ulid string

    • deal_id integer

    • company_id string

    • contact_id integer

    • owner_id integer

    • quote_template_id string

    • folio string

    • reference string

    • version integer

    • title string

    • intro string

    • status string

    • status_label string

    • is_option boolean

    • currency string

    • subtotal object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • discount_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • tax_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • valid_until string

    • shared_at string

    • decided_at string

    • snapshot_hash string

    • external_ref string

    • pdf_url string

    • created_at string

    • updated_at string

Create a quote

Creates a quote as a draft on an existing deal, with its lines. A draft burns no folio and is not visible to the customer: sharing it is a separate, deliberate act that freezes the document (D24).

POST /api/v1/quotes

Body parameters

  • deal_id integer required

    The deal this offer belongs to.

    Example: 7

  • title string required

    Example: Firmado Electrónico

  • intro string

    Opening paragraph, may carry {{quote.*}} variables.

  • valid_until string

    Commercial validity. Defaults to the location's setting.

    Example: 2026-08-14

  • is_option boolean

    Mark it when the customer will choose between several (D25).

    Example: false

  • company_id integer

    Example: 12

  • contact_id integer

    Example: 340

  • quote_template_id integer

    The design to print with.

    Example: 3

  • items object[] required

    The lines. Totals are derived from them.

    • name string required

      Example: Costo de las firmas por volumen

    • quantity string required

      Example: 1100

    • unit_price string required

      Up to four decimals.

      Example: 19.6034

    • unit_label string

      Example: firma

    • tax_rate_id integer

      A tax rate of this location.

      Example: 1

    • discount_percent string

      Example: 0

    • is_informational boolean

      Shows a price and adds nothing.

      Example: false

    • attributes object

      The service's own columns, e.g. {"tokens_por_validacion": 3}.

curl --request POST \
    "https://klozzo.com/api/v1/quotes" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"deal_id\": 7,
    \"title\": \"Firmado Electrónico\",
    \"valid_until\": \"2026-08-14\",
    \"is_option\": false,
    \"company_id\": 12,
    \"contact_id\": 340,
    \"quote_template_id\": 3,
    \"items\": [
        {
            \"name\": \"Costo de las firmas por volumen\",
            \"quantity\": \"1100\",
            \"unit_price\": \"19.6034\",
            \"unit_label\": \"firma\",
            \"tax_rate_id\": 1,
            \"discount_percent\": \"0\",
            \"is_informational\": false
        }
    ]
}"
{
    "data": {
        "id": 1,
        "ulid": "01KYDKV7P4RVYJZZ6JNAJ521YR",
        "deal_id": 15,
        "company_id": null,
        "contact_id": 6295,
        "owner_id": 26,
        "quote_template_id": null,
        "folio": null,
        "reference": "Borrador",
        "version": 1,
        "title": "Patito",
        "intro": null,
        "status": "draft",
        "status_label": "Borrador",
        "is_option": false,
        "currency": "MXN",
        "subtotal": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "discount_total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "tax_total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "valid_until": "2026-08-09",
        "shared_at": null,
        "decided_at": null,
        "snapshot_hash": null,
        "external_ref": null,
        "pdf_url": "http://klozzo.com/api/v1/quotes/01KYDKV7P4RVYJZZ6JNAJ521YR/pdf/signed?893456000&signature=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
        "created_at": "2026-07-25T18:11:14+00:00",
        "updated_at": "2026-07-25T18:11:14+00:00"
    }
}
  • data object

    • id integer

    • ulid string

    • deal_id integer

    • company_id string

    • contact_id integer

    • owner_id integer

    • quote_template_id string

    • folio string

    • reference string

    • version integer

    • title string

    • intro string

    • status string

    • status_label string

    • is_option boolean

    • currency string

    • subtotal object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • discount_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • tax_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • valid_until string

    • shared_at string

    • decided_at string

    • snapshot_hash string

    • external_ref string

    • pdf_url string

    • created_at string

    • updated_at string

Fetch a quote

Returns one quote by its ULID, with its line items and its totals. Money always comes back as an object — amount is an integer at scale 10⁴, decimal is the exact string, formatted is for display. Never parse formatted.

GET /api/v1/quotes/{ulid}

pdf_url is a short-lived signed link you can put straight into your own interface without proxying a token through a browser. It is not the customer's link: that one carries the commercial validity and the read tracking behind it.

Path parameters

  • ulid string required

    Quote ULID (a numeric id still resolves).

    Example: 01JZ8Z0ZP0000000000000000

curl --request GET \
    --get "https://klozzo.com/api/v1/quotes/01JZ8Z0ZP0000000000000000" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": {
        "id": 1,
        "ulid": "01KYDKV7P4RVYJZZ6JNAJ521YR",
        "deal_id": 15,
        "company_id": null,
        "contact_id": 6295,
        "owner_id": 26,
        "quote_template_id": null,
        "folio": null,
        "reference": "Borrador",
        "version": 1,
        "title": "Patito",
        "intro": null,
        "status": "draft",
        "status_label": "Borrador",
        "is_option": false,
        "currency": "MXN",
        "subtotal": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "discount_total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "tax_total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "total": {
            "amount": 0,
            "currency": "MXN",
            "decimal": "0.0000",
            "formatted": "$0.00"
        },
        "valid_until": "2026-08-09",
        "shared_at": null,
        "decided_at": null,
        "snapshot_hash": null,
        "external_ref": null,
        "pdf_url": "http://klozzo.com/api/v1/quotes/01KYDKV7P4RVYJZZ6JNAJ521YR/pdf/signed?893456000&signature=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
        "created_at": "2026-07-25T18:11:14+00:00",
        "updated_at": "2026-07-25T18:11:14+00:00"
    }
}
  • data object

    • id integer

    • ulid string

    • deal_id integer

    • company_id string

    • contact_id integer

    • owner_id integer

    • quote_template_id string

    • folio string

    • reference string

    • version integer

    • title string

    • intro string

    • status string

    • status_label string

    • is_option boolean

    • currency string

    • subtotal object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • discount_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • tax_total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • total object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • valid_until string

    • shared_at string

    • decided_at string

    • snapshot_hash string

    • external_ref string

    • pdf_url string

    • created_at string

    • updated_at string

Download the quote PDF

Returns the PDF of one quote, rendered from the frozen snapshot (D8), so the same quote produces the same bytes in a year's time. Reachable two ways: with an API token, or through the short-lived signed pdf_url the quote resource hands out — which is what lets your own UI show the document without proxying a token through somebody's browser.

GET /api/v1/quotes/{quote_ulid}/pdf

This is not the customer's link. That one is a DocumentLink with the commercial validity, the branded viewer and read tracking behind it (D13).

Path parameters

  • quote_ulid string required

    Quote ULID.

    Example: 01JZ8Z0ZP0000000000000000

curl --request GET \
    --get "https://klozzo.com/api/v1/quotes/01JZ8Z0ZP0000000000000000/pdf" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
"%PDF-1.7 …"

Record a sale

Records a sale for a purchase that happened entirely on your side, with nobody here opening a deal for it — a self-service checkout, a renewal that charged itself. Send the money and the customer; the CRM works out what it means and tells you which rule fired in meta.matched_by.

POST /api/v1/sales

It may attach the sale to an open deal the customer already had, or open one already won and with no owner when there is none — because nobody here attended this customer, and giving the commission to whoever happens to be listed would be worse than leaving it unclaimed. When that happens meta.claimable is true and a seller claims it from the CRM.

Two open deals for the same customer never resolve to a guess: a new deal is opened and the ambiguity is left for a person.

Use POST /api/v1/deals/reconcile instead when the deal already exists and you know which one, and POST /api/v1/payments for a further instalment of a sale already recorded here.

Body parameters

  • external_ref string required

    Your identifier for THIS sale. Recording it twice is impossible.

    Example: sale_88213

  • amount string required

    What was paid. Up to four decimals, separators tolerated.

    Example: 1499.00

  • currency string

    ISO 4217. Defaults to the location's.

    Example: MXN

  • paid_at string

    When the money arrived. Defaults to now.

    Example: 2026-08-23T10:00:00Z

  • method string

    One of transferencia, efectivo, tarjeta, otro. Defaults to tarjeta.

    Example: tarjeta

  • reference string

    Bank or charge reference.

    Example: ch_9912

  • title string

    Title for the deal if one has to be created.

    Example: Plan Pro anual

  • deal_external_ref string

    Point the sale at one specific deal. Answers 404 if that deal is not here.

    Example: sub_44

  • customer object

    Who bought. Required unless deal_external_ref identifies the deal.

    • email string

      Example: ada@example.com

    • phone string

      Example: +52 55 1234 5678

    • phone_country string

      Must not be greater than 2 characters.

      Example: kh

    • first_name string

      Example: Ada

    • last_name string

      Example: Lovelace

    • company_name string

      Example: ADPA

    • company_external_ref string

      Your identifier for the company.

      Example: verificamex-99

  • plan object

    How long what was bought lasts. Omit it for a one-off purchase.

    • name string

      Example: Plan Pro

    • product_sku string

      Matches a product in the catalogue.

      Example: PLAN-PRO

    • external_ref string

      Your identifier for the term. Sending it again EXTENDS the same term instead of opening a second one — that is how a renewal is told from a new sale.

      Example: sub_88213

    • starts_at string

      Defaults to today.

      Example: 2026-08-23

    • ends_at string

      Leave both this and term_months out for a purchase that never expires.

      Example: 2027-08-23

    • term_months integer

      Used to derive ends_at when you do not send one.

      Example: 12

    • auto_renew boolean

      Whether your system will renew it on its own.

      Example: true

curl --request POST \
    "https://klozzo.com/api/v1/sales" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Idempotency-Key: required A unique value per operation. A retry with the same key returns the first answer instead of doing the work again. Example: sale-2026-08-23-88213" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"external_ref\": \"sale_88213\",
    \"amount\": \"1499.00\",
    \"currency\": \"MXN\",
    \"paid_at\": \"2026-08-23T10:00:00Z\",
    \"method\": \"tarjeta\",
    \"reference\": \"ch_9912\",
    \"title\": \"Plan Pro anual\",
    \"deal_external_ref\": \"sub_44\",
    \"customer\": {
        \"email\": \"ada@example.com\",
        \"phone\": \"+52 55 1234 5678\",
        \"phone_country\": \"kh\",
        \"first_name\": \"Ada\",
        \"last_name\": \"Lovelace\",
        \"company_name\": \"ADPA\",
        \"company_external_ref\": \"verificamex-99\"
    },
    \"plan\": {
        \"name\": \"Plan Pro\",
        \"product_sku\": \"PLAN-PRO\",
        \"external_ref\": \"sub_88213\",
        \"starts_at\": \"2026-08-23\",
        \"ends_at\": \"2027-08-23\",
        \"term_months\": 12,
        \"auto_renew\": true
    }
}"
{
    "meta": {
        "created": false,
        "matched_by": "payment_external_ref"
    }
}
  • meta object

    • created boolean

    • matched_by string

List payments

Lists the payments recorded in this location, most recent first. Use it to check what your side has already reported before reporting it again — ?external_ref= finds the one carrying your charge identifier, which is the cheapest way to answer "did that webhook land?".

GET /api/v1/payments

Query parameters

  • deal_id integer

    Only this deal's payments.

    Example: 7

  • external_ref string

    Find the one carrying your identifier.

    Example: spei-8891

  • per_page integer

    Rows per page. Default 50, maximum 100. See Lists, paging and filters.

    Example: 50

curl --request GET \
    --get "https://klozzo.com/api/v1/payments?deal_id=7&external_ref=spei-8891&per_page=50" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
{
    "data": [
        {
            "id": null,
            "deal_id": null,
            "quote_id": null,
            "subscription_id": null,
            "amount": {
                "amount": 100000000,
                "currency": "MXN",
                "decimal": "10000.0000",
                "formatted": "$10,000.00"
            },
            "currency": "MXN",
            "paid_at": "2026-08-17T02:19:50+00:00",
            "method": "transferencia",
            "method_label": "Transferencia",
            "origin": null,
            "reference": "SPEI-3724",
            "note": null,
            "recorded_by": null,
            "external_ref": null,
            "created_at": null
        },
        {
            "id": null,
            "deal_id": null,
            "quote_id": null,
            "subscription_id": null,
            "amount": {
                "amount": 100000000,
                "currency": "MXN",
                "decimal": "10000.0000",
                "formatted": "$10,000.00"
            },
            "currency": "MXN",
            "paid_at": "2026-08-15T02:19:50+00:00",
            "method": "transferencia",
            "method_label": "Transferencia",
            "origin": null,
            "reference": "SPEI-0432",
            "note": null,
            "recorded_by": null,
            "external_ref": null,
            "created_at": null
        }
    ]
}
  • data object[]

    • id string

    • deal_id string

    • quote_id string

    • subscription_id string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • paid_at string

    • method string

    • method_label string

    • origin string

    • reference string

    • note string

    • recorded_by string

    • external_ref string

    • created_at string

Record a payment

Records a payment against a deal that already exists. It does not close the deal and it does not accept a quote — use POST /api/v1/deals/reconcile when the payment is what closes the sale, or POST /api/v1/sales when there was never a deal to begin with.

POST /api/v1/payments

Instalments are several calls against the same deal_id; give each one its own external_ref so a retry of the second never looks like the first.

Body parameters

  • deal_id integer required

    The deal being paid.

    Example: 7

  • quote_id integer

    The quote it settles, when there is one.

    Example: 15

  • amount string required

    Up to four decimals, separators tolerated.

    Example: 25013.94

  • paid_at string required

    When the money arrived.

    Example: 2026-08-02

  • method string

    One of transferencia, efectivo, tarjeta, otro.

    Example: transferencia

  • reference string

    Bank reference.

    Example: SPEI-8891

  • note string

    Example: Primer parcialidad

  • external_ref string

    Your identifier for this payment.

    Example: charge_9912

curl --request POST \
    "https://klozzo.com/api/v1/payments" \
    --header "Authorization: Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"deal_id\": 7,
    \"quote_id\": 15,
    \"amount\": \"25013.94\",
    \"paid_at\": \"2026-08-02\",
    \"method\": \"transferencia\",
    \"reference\": \"SPEI-8891\",
    \"note\": \"Primer parcialidad\",
    \"external_ref\": \"charge_9912\"
}"
{
    "data": {
        "id": null,
        "deal_id": null,
        "quote_id": null,
        "subscription_id": null,
        "amount": {
            "amount": 100000000,
            "currency": "MXN",
            "decimal": "10000.0000",
            "formatted": "$10,000.00"
        },
        "currency": "MXN",
        "paid_at": "2026-08-12T02:19:50+00:00",
        "method": "transferencia",
        "method_label": "Transferencia",
        "origin": null,
        "reference": "SPEI-0564",
        "note": null,
        "recorded_by": null,
        "external_ref": null,
        "created_at": null
    }
}
  • data object

    • id string

    • deal_id string

    • quote_id string

    • subscription_id string

    • amount object

      • amount integer

      • currency string

      • decimal string

      • formatted string

    • currency string

    • paid_at string

    • method string

    • method_label string

    • origin string

    • reference string

    • note string

    • recorded_by string

    • external_ref string

    • created_at string