API Documentation
Build powerful integrations with our comprehensive REST API. Manage invoices, customers, payments, and more programmatically.
Authentication
All API requests require authentication using an API key. Include your API key in the Authorization header as a Bearer token:
curl "https://invoicematic.com/api/v1/api/me" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
The base URL for all API endpoints is: https://invoicematic.com/api/v1/api
API Keys
API keys can be created in Settings > API Keys. Each key has specific scopes that determine what resources it can access and what actions it can perform.
Keep your API keys secure
Never share your API keys in publicly accessible areas such as GitHub, client-side code, etc.
Key Format
API keys are prefixed with is_key_ for easy identification. Keys can optionally have an expiration date and an IP allowlist.
Available Scopes
Scopes control what an API key can access. A :read scope allows listing and viewing resources. A :write scope allows creating, updating, and deleting.
invoices:read
invoices:write
estimates:read
estimates:write
customers:read
customers:write
payments:read
payments:write
expenses:read
expenses:write
items:read
items:write
reports:read
settings:read
settings:write
API Endpoints
Base URL: https://invoicematic.com/api/v1
/health
Check API health status. No scope required.
Response
{
"status": "healthy",
"timestamp": "2026-02-07T10:30:00Z",
"version": "2.2.0"
}
/api/me
Get information about the authenticated company and API key. No scope required.
Response
{
"company": {
"id": 1,
"name": "Acme Corp",
"slug": "acme-corp",
"address": {
"address_street_1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country_id": 231,
"phone": "+1 555-0100"
},
"logo": null
},
"api_key": {
"name": "Production Key",
"scopes": ["invoices:read", "invoices:write", "customers:read"],
"expires_at": "2027-01-15T00:00:00+00:00",
"last_used_at": "2026-02-07T10:30:00+00:00"
}
}
Invoices
/api/invoices
invoices:read
List all invoices. Supports pagination and filtering.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 10) |
status | string | Filter by status: DRAFT, SENT, VIEWED, OVERDUE, COMPLETED |
customer_id | integer | Filter by customer |
Example Request
curl "https://invoicematic.com/api/v1/api/invoices?page=1&limit=5" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"invoice_date": "2026-02-01",
"due_date": "2026-03-01",
"invoice_number": "INV-000001",
"reference_number": "REF-100",
"status": "SENT",
"paid_status": "UNPAID",
"discount_type": "fixed",
"discount": 0,
"discount_val": 0,
"sub_total": 50000,
"total": 50000,
"tax": 0,
"due_amount": 50000,
"currency_id": 1,
"exchange_rate": 1,
"customer_id": 1,
"template_name": "invoice1",
"creator_id": 1,
"unique_hash": "abc123...",
"customer": {
"id": 1,
"name": "John Doe",
"email": "[email protected]"
},
"items": [
{
"id": 1,
"name": "Web Design",
"description": "Homepage redesign",
"quantity": 1,
"price": 50000,
"total": 50000
}
]
}
],
"links": { "first": "...?page=1", "last": "...?page=3", "prev": null, "next": "...?page=2" },
"meta": { "current_page": 1, "last_page": 3, "per_page": 5, "total": 12 }
}
/api/invoices
invoices:write
Create a new invoice. All monetary values are in cents (e.g. 10000 = $100.00).
Required Fields
| Field | Type | Description |
|---|---|---|
invoice_date | string | Invoice date (YYYY-MM-DD) |
due_date | string | Due date (YYYY-MM-DD, optional) |
customer_id | integer | Customer ID |
invoice_number | string | Unique invoice number |
discount | number | Discount percentage or fixed amount |
discount_val | integer | Discount value in cents |
sub_total | number | Subtotal in cents |
total | number | Total in cents |
tax | number | Tax amount in cents |
template_name | string | PDF template (e.g. "invoice1") |
items | array | Line items (see below) |
items.*.name | string | Item name |
items.*.quantity | number | Quantity |
items.*.price | number | Unit price in cents |
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/invoices" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"invoice_date": "2026-02-07",
"due_date": "2026-03-07",
"customer_id": 1,
"invoice_number": "INV-000042",
"discount": 0,
"discount_val": 0,
"sub_total": 150000,
"total": 150000,
"tax": 0,
"template_name": "invoice1",
"items": [
{
"name": "Web Development",
"description": "Frontend implementation",
"quantity": 10,
"price": 15000
}
]
}'
Example Response
{
"data": {
"id": 42,
"invoice_date": "2026-02-07",
"due_date": "2026-03-07",
"invoice_number": "INV-000042",
"status": "DRAFT",
"paid_status": "UNPAID",
"sub_total": 150000,
"total": 150000,
"tax": 0,
"due_amount": 150000,
"discount": 0,
"discount_val": 0,
"customer_id": 1,
"currency_id": 1,
"exchange_rate": 1,
"template_name": "invoice1",
"creator_id": 1,
"unique_hash": "xyz789...",
"items": [
{
"id": 100,
"name": "Web Development",
"description": "Frontend implementation",
"quantity": 10,
"price": 15000,
"total": 150000
}
]
}
}
/api/invoices/{'{id}'}
Get a single invoice
invoices:read
/api/invoices/{'{id}'}
Update an invoice
invoices:write
/api/invoices/{'{id}'}
Delete an invoice
invoices:write
Customers
/api/customers
customers:read
List all customers. Supports pagination and filtering.
Example Request
curl "https://invoicematic.com/api/v1/api/customers?limit=10" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"phone": "+1 555-0100",
"contact_name": "John",
"company_name": "Doe Industries",
"website": "https://doe.example.com",
"currency_id": 1,
"prefix": "Mr",
"created_at": "2026-01-15T08:00:00.000000Z",
"billing": {
"name": "John Doe",
"address_street_1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country_id": 231,
"phone": "+1 555-0100"
},
"shipping": null
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 1 }
}
/api/customers
customers:write
Create a new customer.
Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Required. Customer name |
email | string | Email address (unique per company) |
phone | string | Phone number |
contact_name | string | Contact person name |
company_name | string | Company name |
website | string | Website URL |
currency_id | integer | Currency ID |
billing | object | Billing address (name, address_street_1, city, state, zip, country_id, phone) |
shipping | object | Shipping address (same fields as billing) |
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/customers" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"email": "[email protected]",
"phone": "+1 555-0200",
"company_name": "Smith Co",
"currency_id": 1,
"billing": {
"name": "Jane Smith",
"address_street_1": "456 Oak Ave",
"city": "San Francisco",
"state": "CA",
"zip": "94102",
"country_id": 231
}
}'
Example Response
{
"data": {
"id": 5,
"name": "Jane Smith",
"email": "[email protected]",
"phone": "+1 555-0200",
"company_name": "Smith Co",
"currency_id": 1,
"company_id": 1,
"creator_id": 1,
"created_at": "2026-02-07T12:00:00.000000Z",
"billing": {
"name": "Jane Smith",
"address_street_1": "456 Oak Ave",
"city": "San Francisco",
"state": "CA",
"zip": "94102",
"country_id": 231
}
}
}
/api/customers/{'{id}'}
Get a single customer
customers:read
/api/customers/{'{id}'}
Update a customer
customers:write
Payments
/api/payments
payments:read
List all payments. Supports pagination and filtering.
Example Request
curl "https://invoicematic.com/api/v1/api/payments" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"payment_number": "PAY-000001",
"payment_date": "2026-02-05",
"amount": 50000,
"notes": "Payment received via bank transfer",
"customer_id": 1,
"invoice_id": 1,
"payment_method_id": 1,
"currency_id": 1,
"exchange_rate": 1,
"base_amount": 50000,
"creator_id": 1,
"customer": {
"id": 1,
"name": "John Doe"
},
"payment_method": {
"id": 1,
"name": "Bank Transfer"
}
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 1 }
}
/api/payments
payments:write
Record a new payment. Monetary values are in cents.
Required Fields
| Field | Type | Description |
|---|---|---|
payment_date | string | Required. Payment date (YYYY-MM-DD) |
customer_id | integer | Required. Customer ID |
amount | integer | Required. Amount in cents |
payment_number | string | Required. Unique payment number |
invoice_id | integer | Invoice to apply payment to |
payment_method_id | integer | Payment method ID |
notes | string | Payment notes |
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/payments" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"payment_date": "2026-02-07",
"customer_id": 1,
"amount": 50000,
"payment_number": "PAY-000010",
"invoice_id": 1,
"payment_method_id": 1,
"notes": "Wire transfer received"
}'
Example Response
{
"data": {
"id": 10,
"payment_number": "PAY-000010",
"payment_date": "2026-02-07",
"amount": 50000,
"notes": "Wire transfer received",
"customer_id": 1,
"invoice_id": 1,
"payment_method_id": 1,
"currency_id": 1,
"exchange_rate": 1,
"base_amount": 50000,
"creator_id": 1
}
}
/api/payments/{'{id}'}
Get a single payment
payments:read
/api/payments/{'{id}'}
Update a payment
payments:write
Estimates
/api/estimates
estimates:read
List all estimates. Supports pagination and filtering.
Example Request
curl "https://invoicematic.com/api/v1/api/estimates" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"estimate_date": "2026-02-01",
"expiry_date": "2026-03-01",
"estimate_number": "EST-000001",
"status": "DRAFT",
"discount_type": "fixed",
"discount": 0,
"discount_val": 0,
"sub_total": 75000,
"total": 75000,
"tax": 0,
"currency_id": 1,
"exchange_rate": 1,
"customer_id": 1,
"template_name": "estimate1",
"creator_id": 1,
"customer": {
"id": 1,
"name": "John Doe"
},
"items": [
{
"id": 1,
"name": "Consulting",
"quantity": 5,
"price": 15000,
"total": 75000
}
]
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 1 }
}
/api/estimates
estimates:write
Create a new estimate. Accepts the same item structure as invoices.
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/estimates" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"estimate_date": "2026-02-07",
"expiry_date": "2026-03-07",
"customer_id": 1,
"estimate_number": "EST-000005",
"discount": 0,
"discount_val": 0,
"sub_total": 200000,
"total": 200000,
"tax": 0,
"template_name": "estimate1",
"items": [
{
"name": "Strategy Consulting",
"description": "Market analysis and growth strategy",
"quantity": 20,
"price": 10000
}
]
}'
/api/estimates/{'{id}'}
Get a single estimate
estimates:read
/api/estimates/{'{id}'}
Update an estimate
estimates:write
/api/estimates/{'{id}'}
Delete an estimate
estimates:write
Expenses
/api/expenses
expenses:read
List all expenses. Supports pagination and filtering.
Example Request
curl "https://invoicematic.com/api/v1/api/expenses" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"expense_date": "2026-02-03",
"expense_number": "EXP-000001",
"amount": 12500,
"notes": "Office supplies purchase",
"customer_id": null,
"expense_category_id": 2,
"currency_id": 1,
"exchange_rate": 1,
"base_amount": 12500,
"payment_method_id": 1,
"creator_id": 1,
"expense_category": {
"id": 2,
"name": "Office Supplies"
}
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 1 }
}
/api/expenses
expenses:write
Create a new expense.
Required Fields
| Field | Type | Description |
|---|---|---|
expense_date | string | Required. Expense date (YYYY-MM-DD) |
expense_category_id | integer | Required. Expense category ID |
amount | integer | Required. Amount in cents |
currency_id | integer | Required. Currency ID |
customer_id | integer | Associated customer |
payment_method_id | integer | Payment method used |
notes | string | Notes about the expense |
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/expenses" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"expense_date": "2026-02-07",
"expense_category_id": 2,
"amount": 4500,
"currency_id": 1,
"notes": "Team lunch"
}'
/api/expenses/{'{id}'}
Get a single expense
expenses:read
/api/expenses/{'{id}'}
Update an expense
expenses:write
/api/expenses/{'{id}'}
Delete an expense
expenses:write
Items
/api/items
items:read
List all items in the product/service catalog.
Example Request
curl "https://invoicematic.com/api/v1/api/items" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json"
Example Response
{
"data": [
{
"id": 1,
"name": "Web Development",
"description": "Full-stack web development services",
"price": 15000,
"unit_id": 1,
"company_id": 1,
"creator_id": 1,
"currency_id": 1,
"tax_per_item": "NO",
"created_at": "2026-01-10T08:00:00.000000Z",
"unit": {
"id": 1,
"name": "hour"
}
},
{
"id": 2,
"name": "Logo Design",
"description": "Custom logo and brand identity",
"price": 250000,
"unit_id": null,
"company_id": 1,
"creator_id": 1,
"currency_id": 1,
"tax_per_item": "NO",
"created_at": "2026-01-12T10:00:00.000000Z"
}
],
"links": { "first": "...?page=1", "last": "...?page=1", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 2 }
}
/api/items
items:write
Create a new item in the product/service catalog.
Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Required. Item name |
price | integer | Required. Price in cents |
description | string | Item description |
unit_id | integer | Unit of measure ID |
Example Request
curl -X POST "https://invoicematic.com/api/v1/api/items" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"name": "SEO Audit",
"description": "Comprehensive SEO analysis and recommendations",
"price": 75000
}'
Example Response
{
"data": {
"id": 3,
"name": "SEO Audit",
"description": "Comprehensive SEO analysis and recommendations",
"price": 75000,
"unit_id": null,
"company_id": 1,
"creator_id": 1,
"currency_id": 1,
"tax_per_item": null,
"created_at": "2026-02-07T12:00:00.000000Z",
"updated_at": "2026-02-07T12:00:00.000000Z"
}
}
/api/items/{'{id}'}
Get a single item
items:read
/api/items/{'{id}'}
Update an item
items:write
/api/items/{'{id}'}
Delete an item
items:write
Pagination
All list endpoints return paginated results. Control pagination with the page and limit query parameters.
GET /api/v1/api/invoices?page=2&limit=25
Paginated responses include links and meta objects:
{
"data": [ ... ],
"links": {
"first": "...?page=1",
"last": "...?page=5",
"prev": "...?page=1",
"next": "...?page=3"
},
"meta": {
"current_page": 2,
"from": 26,
"last_page": 5,
"per_page": 25,
"to": 50,
"total": 120
}
}
Webhooks
Webhooks allow you to receive real-time notifications when events occur in your account. Configure webhooks in Settings > Webhooks.
Available Events
invoice.created
invoice.updated
invoice.deleted
invoice.sent
invoice.viewed
invoice.paid
invoice.overdue
estimate.created
estimate.updated
estimate.deleted
estimate.sent
estimate.accepted
estimate.rejected
customer.created
customer.updated
customer.deleted
payment.received
payment.deleted
expense.created
expense.updated
expense.deleted
Webhook Payload
Each webhook delivery includes the following headers:
| Header | Description |
|---|---|
X-Webhook-Signature | HMAC-SHA256 signature of the payload |
X-Webhook-Event | The event name (e.g. invoice.created) |
X-Webhook-Delivery-Id | Unique delivery ID |
X-Webhook-Timestamp | Unix timestamp of the delivery |
{
"event": "invoice.created",
"timestamp": "2026-02-07T10:30:00Z",
"data": {
"id": 42,
"invoice_number": "INV-000042",
"status": "DRAFT",
"total": 150000,
"customer_id": 1,
...
}
}
Signature Verification
Verify webhook signatures to ensure deliveries came from Invoicematic. Compare the X-Webhook-Signature header against an HMAC-SHA256 hash of the raw request body using your webhook secret.
// PHP
$signature = hash_hmac('sha256', $payload, $webhookSecret);
$isValid = hash_equals($signature, $requestSignature);
// Node.js
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', webhookSecret).update(payload).digest('hex');
const isValid = crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(requestSignature));
Idempotency
For POST and PUT requests, include an Idempotency-Key header to ensure the operation is only performed once, even if the request is retried.
curl -X POST "https://invoicematic.com/api/v1/api/invoices" \
-H "Authorization: Bearer is_key_your_api_key_here" \
-H "Idempotency-Key: unique-request-id-123" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"customer_id": 1, ...}'
Idempotency keys expire after 24 hours. If you retry a request with the same key within that window, you'll receive the same response without the operation being performed again.
Error Handling
The API uses standard HTTP status codes. Error responses include a JSON body with details.
Validation Error (422)
{
"message": "The given data was invalid.",
"errors": {
"customer_id": ["The customer id field is required."],
"invoice_number": ["The invoice number has already been taken."]
}
}
Authentication Error (401)
{
"error": "unauthorized",
"message": "Invalid API key."
}
Scope Error (403)
{
"error": "forbidden",
"message": "Your API key does not have the required scope(s): invoices:write"
}