Skip to main content
Bill Pay is Meow’s accounts-payable surface. You record what you owe a vendor as a bill — its line items, due date, and how it should be paid — and the API saves it as a draft. Someone on your team approves the bill in the Meow dashboard, and only then does it get paid.
Every bill you touch through the API stays a draft pending approval. Creating a bill, editing it, or attaching documents never moves money on its own — payment happens only after a human approves the bill in the dashboard.

You’ll need

  • An API key with billpay:read to list and retrieve bills, and billpay:write to create, update, delete, and attach documents to them.
  • A contact for each vendor, created with banking (ACH, wire, or check) counterparty details. A bill is payable to a contact that must already exist; create one first with POST /contacts. (The Contacts guide covers USDC crypto contacts, which Bill Pay doesn’t use.)
  • If your key can access more than one entity, pass the x-entity-id header to choose which entity the bill belongs to.

1. Create a bill

A bill is payable to a contact_id and is made of one or more line items. Each line item is either an EXPENSE (a flat amount) or an ITEM (a unit amount times a quantity); the bill total is calculated from the lines. Send a unique idempotency_key so a retried request never creates a duplicate.
curl -X POST https://api.meow.com/v1/bills \
  -H "x-api-key: $MEOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "bill-2026-06-30-catnip-001",
    "contact_id": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "invoice_number": "CATNIP-4471",
    "bill_date": "2026-06-30",
    "bill_due_date": "2026-07-30",
    "description": "June cloud hosting",
    "memo": "Approved by ops",
    "payment_type": "ACH",
    "currency": "USD",
    "line_items": [
      { "type": "EXPENSE", "amount": 1200.00, "description": "Cloud hosting - June" },
      { "type": "ITEM", "amount": 15.00, "quantity": 20, "description": "Extra storage (GB)" }
    ]
  }'
Response
{
  "id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
  "status": "DRAFT",
  "vendor_name": "Catnip Cloud",
  "invoice_number": "CATNIP-4471",
  "description": "June cloud hosting",
  "bill_date": "2026-06-30",
  "bill_due_date": "2026-07-30",
  "bill_total": "1500.00",
  "currency": "USD",
  "payment_type": "ACH",
  "contact_id": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "created_at": "2026-06-30T10:30:00.000Z",
  "line_items": [
    { "id": "1a2b3c4d-...", "type": "EXPENSE", "amount": "1200.00", "quantity": null, "description": "Cloud hosting - June", "amount_total": "1200.00" },
    { "id": "2b3c4d5e-...", "type": "ITEM", "amount": "15.00", "quantity": "20", "description": "Extra storage (GB)", "amount_total": "300.00" }
  ]
}
Save id — it’s the {bill_id} for attaching documents, tracking, updating, or canceling the bill below.
FieldDescription
idempotency_keyRequired. A key you generate so retrying never creates a duplicate bill; reusing a key is rejected.
contact_idThe vendor this bill is payable to. The vendor must already exist as a contact.
payment_typeHow the bill is paid once approved: ACH (default), WIRE, or CHECK.
account_idThe account to pay from, in the id format returned by GET /accounts. Defaults to your configured bill pay account.
currencyThe bill’s currency (ISO 4217). Defaults to USD.
bill_date / bill_due_dateThe date on the bill and the date it’s due (YYYY-MM-DD).
line_itemsThe lines that make up the bill. Use type: "ITEM" with a quantity for itemized lines, or type: "EXPENSE" for a flat amount.
rruleAn iCalendar RRULE to make this a recurring bill.
Bill Pay accepts the ACH, WIRE, and CHECK payment types. Crypto and international payments are arranged in the Meow dashboard, not through this API.

2. Attach supporting documents

Attaching the vendor’s invoice or a receipt is a three-step flow: ask for upload URLs, upload each file, then confirm the attachment. You can attach up to five documents per confirm call.
1

Request upload URLs

Describe each file — its filename, content_type, and size in bytes — and get a short-lived upload target for each.
curl -X POST https://api.meow.com/v1/bills/$BILL_ID/documents/presigned-urls \
  -H "x-api-key: $MEOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "files": [ { "filename": "catnip-cloud-4471.pdf", "content_type": "application/pdf", "size": 48213 } ] }'
Response
{
  "uploads": [
    {
      "url": "https://uploads.meow.com/billpay",
      "fields": { "key": "billpay/9a8b.../catnip-cloud-4471.pdf", "policy": "eyJ...", "x-amz-signature": "abc123" },
      "object_key": "billpay/9a8b.../catnip-cloud-4471.pdf",
      "filename": "catnip-cloud-4471.pdf",
      "max_bytes": 10485760
    }
  ]
}
2

Upload each file

POST the file to its url as a multipart form, including every entry from fields and putting the file last. Keep it under max_bytes and upload before the URL expires.
curl -X POST "https://uploads.meow.com/billpay" \
  -F "key=billpay/9a8b.../catnip-cloud-4471.pdf" \
  -F "policy=eyJ..." \
  -F "x-amz-signature=abc123" \
  -F "file=@catnip-cloud-4471.pdf"
3

Confirm the attachment

Confirm each upload with the object_key and filename you received. The response is the updated bill, now carrying the document under additional_documents with a short-lived download URL.
curl -X POST https://api.meow.com/v1/bills/$BILL_ID/documents \
  -H "x-api-key: $MEOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "documents": [ { "object_key": "billpay/9a8b.../catnip-cloud-4471.pdf", "filename": "catnip-cloud-4471.pdf" } ] }'
Response
{
  "id": "9a8b7c6d-...",
  "status": "DRAFT",
  "vendor_name": "Catnip Cloud",
  "additional_documents": [
    { "id": "d1e2f3a4-...", "name": "catnip-cloud-4471.pdf", "url": "https://download.meow.com/...", "created_at": "2026-06-30T10:32:00.000Z" }
  ]
}

3. Track bills

GET /bills returns a paginated list and filters by status, vendor, amount, and date ranges, plus full-text search.
curl "https://api.meow.com/v1/bills?statuses=DRAFT&statuses=PENDING&due_date_to=2026-07-31&limit=25" \
  -H "x-api-key: $MEOW_API_KEY"
ParameterDescription
statusesFilter by one or more bill statuses; repeat the parameter for several.
contact_idFilter to bills payable to specific vendors.
amount_min / amount_maxFilter by bill total.
bill_date_from / bill_date_toFilter by the date on the bill.
due_date_from / due_date_toFilter by due date.
searchFull-text search across bill fields.
sort_by / sort_descendingOrder the results.
limit / offsetPage through results using the nextOffset from the previous response.
Retrieve one bill with GET /bills/{bill_id}:
curl https://api.meow.com/v1/bills/$BILL_ID -H "x-api-key: $MEOW_API_KEY"
A bill moves through these statuses as it’s approved and paid:
statusMeaning
DRAFTCreated and waiting for approval in the dashboard.
PENDINGSubmitted and moving through approval.
APPROVEDApproved and ready to be scheduled.
SCHEDULEDApproved with a payment scheduled; see scheduled_at.
PAYMENT_INITIATEDPayment is on its way.
PAYMENT_DELIVEREDPayment delivered; see paid_at.
PAYMENT_FAILEDThe payment attempt failed.
REJECTEDAn approver declined the bill.
CANCELEDThe bill was canceled before payment.

4. Update or cancel a draft

While a bill is still a DRAFT, you can edit it. PATCH uses partial semantics — only the fields you send change, and sending line_items replaces the existing lines (send an empty list to clear them).
curl -X PATCH https://api.meow.com/v1/bills/$BILL_ID \
  -H "x-api-key: $MEOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "memo": "Revised per updated invoice", "payment_type": "WIRE" }'
Cancel a bill that hasn’t been approved yet by deleting it:
curl -X DELETE https://api.meow.com/v1/bills/$BILL_ID -H "x-api-key: $MEOW_API_KEY"
Once a bill is approved (or paid), it can no longer be edited or deleted through the API.

5. Schedule recurring bills

To generate a bill on a repeating schedule, include an iCalendar rrule (with a DTSTART) when you create it. Each occurrence is generated as its own draft for approval — recurring bills are never paid automatically.
curl -X POST https://api.meow.com/v1/bills \
  -H "x-api-key: $MEOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "bill-rent-recurring-001",
    "contact_id": "c4d5e6f7-8a9b-0c1d-2e3f-4a5b6c7d8e9f",
    "description": "Monthly office rent",
    "payment_type": "ACH",
    "rrule": "DTSTART:20260701T000000Z\nRRULE:FREQ=MONTHLY;BYMONTHDAY=1",
    "line_items": [ { "type": "EXPENSE", "amount": 4500.00, "description": "Office rent — Whisker Works" } ]
  }'
Building the schedule string by hand is fiddly. A tool like the RRULE generator will assemble the DTSTART/RRULE for you.

End to end

# 1. Create the bill and capture its id.
BILL_ID=$(curl -s -X POST https://api.meow.com/v1/bills \
  -H "x-api-key: $MEOW_API_KEY" -H "Content-Type: application/json" \
  -d '{"idempotency_key":"bill-'"$(date +%Y%m%d)"'-catnip-001","contact_id":"b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d","invoice_number":"CATNIP-4471","payment_type":"ACH","line_items":[{"type":"EXPENSE","amount":1200.00,"description":"Cloud hosting - June"}]}' \
  | jq -r .id)

# 2. Request an upload URL for the vendor's invoice PDF.
UPLOAD=$(curl -s -X POST https://api.meow.com/v1/bills/$BILL_ID/documents/presigned-urls \
  -H "x-api-key: $MEOW_API_KEY" -H "Content-Type: application/json" \
  -d '{"files":[{"filename":"catnip-cloud-4471.pdf","content_type":"application/pdf","size":48213}]}')
OBJECT_KEY=$(echo "$UPLOAD" | jq -r '.uploads[0].object_key')

# 3. Upload the file to .uploads[0].url with .uploads[0].fields, then confirm.
curl -s -X POST https://api.meow.com/v1/bills/$BILL_ID/documents \
  -H "x-api-key: $MEOW_API_KEY" -H "Content-Type: application/json" \
  -d "{\"documents\":[{\"object_key\":\"$OBJECT_KEY\",\"filename\":\"catnip-cloud-4471.pdf\"}]}" | jq '.status'
The bill now sits as a DRAFT with its invoice attached, waiting for an approver in the dashboard.

See also

Create a contact

Register a vendor with banking counterparty details to pay bills to.

Create a bill

Full request contract for POST /bills.

List bills

Every filter, sort, and pagination option.

Update a bill

Edit a draft with PATCH partial semantics.

Confirm bill documents

Attach uploaded invoices and receipts.