Authenticated API
This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.
Check Splitting API
Split checks by item, seat, amount, or custom configuration for flexible bill payment.
Overview
The Check Splitting API enables restaurants to split a single check into multiple payments, supporting common scenarios like splitting by item, dividing equally, or custom distributions.
| Split Type | Description | Use Case |
|---|---|---|
| By Item | Each guest pays for their items | Individual orders |
| By Seat | Items assigned to seat positions | Table service |
| Equal Split | Divide total equally | Group dining |
| Custom Amount | Specify exact amounts | Partial payments |
| Percentage | Split by percentage | Cost sharing |
Check Model (Split View)
{
"check_id": "chk_abc123",
"order_id": "ord_xyz789",
"table_id": "tbl_001",
"original_total": 156.50,
"split_status": "partial",
"splits": [
{
"split_id": "spl_001",
"seat": 1,
"guest_name": "John",
"items": ["item_001", "item_002"],
"subtotal": 42.50,
"tax": 3.83,
"tip": 8.00,
"total": 54.33,
"status": "paid",
"payment_id": "pay_001"
},
{
"split_id": "spl_002",
"seat": 2,
"guest_name": "Jane",
"items": ["item_003", "item_004"],
"subtotal": 38.00,
"tax": 3.42,
"tip": null,
"total": 41.42,
"status": "pending"
}
],
"remaining_balance": 60.75,
"created_at": "2026-01-18T19:30:00Z"
}
Endpoints
Initialize Split
POST /v1/checks/{check_id}/split/initialize
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"split_type": "by_seat",
"seats": [
{"seat": 1, "guest_name": "John"},
{"seat": 2, "guest_name": "Jane"},
{"seat": 3, "guest_name": "Bob"}
]
}
Response:
{
"check_id": "chk_abc123",
"split_type": "by_seat",
"splits": [
{"split_id": "spl_001", "seat": 1, "guest_name": "John", "items": [], "total": 0},
{"split_id": "spl_002", "seat": 2, "guest_name": "Jane", "items": [], "total": 0},
{"split_id": "spl_003", "seat": 3, "guest_name": "Bob", "items": [], "total": 0}
],
"unassigned_items": [
{"id": "item_001", "name": "Steak", "price": 45.00},
{"id": "item_002", "name": "Salad", "price": 12.00},
{"id": "item_003", "name": "Wine", "price": 36.00}
]
}
Split By Item
POST /v1/checks/{check_id}/split/by-item
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"assignments": [
{"item_id": "item_001", "split_id": "spl_001"},
{"item_id": "item_002", "split_id": "spl_002"},
{"item_id": "item_003", "split_id": "spl_001"}
]
}
Response:
{
"check_id": "chk_abc123",
"splits": [
{
"split_id": "spl_001",
"items": [
{"id": "item_001", "name": "Steak", "price": 45.00},
{"id": "item_003", "name": "Wine", "price": 36.00}
],
"subtotal": 81.00,
"tax": 7.29,
"total": 88.29
},
{
"split_id": "spl_002",
"items": [
{"id": "item_002", "name": "Salad", "price": 12.00}
],
"subtotal": 12.00,
"tax": 1.08,
"total": 13.08
}
]
}
Split Equally
POST /v1/checks/{check_id}/split/equal
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"ways": 3,
"include_tip": true,
"tip_percentage": 20
}
Response:
{
"check_id": "chk_abc123",
"original_total": 156.50,
"tip_amount": 31.30,
"grand_total": 187.80,
"splits": [
{"split_id": "spl_001", "total": 62.60, "status": "pending"},
{"split_id": "spl_002", "total": 62.60, "status": "pending"},
{"split_id": "spl_003", "total": 62.60, "status": "pending"}
]
}
Split By Custom Amount
POST /v1/checks/{check_id}/split/custom
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"amounts": [
{"split_id": "spl_001", "amount": 50.00},
{"split_id": "spl_002", "amount": 75.00}
]
}
Response:
{
"check_id": "chk_abc123",
"splits": [
{"split_id": "spl_001", "amount": 50.00, "status": "pending"},
{"split_id": "spl_002", "amount": 75.00, "status": "pending"}
],
"remaining": 31.50,
"remaining_split_id": "spl_003"
}
Split By Percentage
POST /v1/checks/{check_id}/split/percentage
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"percentages": [
{"split_id": "spl_001", "percentage": 40},
{"split_id": "spl_002", "percentage": 35},
{"split_id": "spl_003", "percentage": 25}
]
}
Response:
{
"check_id": "chk_abc123",
"original_total": 156.50,
"splits": [
{"split_id": "spl_001", "percentage": 40, "amount": 62.60},
{"split_id": "spl_002", "percentage": 35, "amount": 54.78},
{"split_id": "spl_003", "percentage": 25, "amount": 39.12}
]
}
Move Item Between Splits
POST /v1/checks/{check_id}/split/move-item
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"item_id": "item_003",
"from_split_id": "spl_001",
"to_split_id": "spl_002"
}
Response:
{
"success": true,
"updated_splits": [
{"split_id": "spl_001", "subtotal": 45.00, "total": 49.05},
{"split_id": "spl_002", "subtotal": 48.00, "total": 52.32}
]
}
Share Item Across Splits
POST /v1/checks/{check_id}/split/share-item
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"item_id": "item_004",
"share_with": ["spl_001", "spl_002", "spl_003"],
"distribution": "equal"
}
Response:
{
"item_id": "item_004",
"item_name": "Appetizer Sampler",
"original_price": 24.00,
"shared_portions": [
{"split_id": "spl_001", "amount": 8.00},
{"split_id": "spl_002", "amount": 8.00},
{"split_id": "spl_003", "amount": 8.00}
]
}
Payment Operations
Pay Single Split
POST /v1/checks/{check_id}/splits/{split_id}/pay
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"payment_method": "card",
"card_token": "tok_visa_1234",
"tip_amount": 10.00
}
Response:
{
"split_id": "spl_001",
"payment_id": "pay_abc123",
"amount_paid": 62.60,
"tip": 10.00,
"total_charged": 72.60,
"status": "paid",
"remaining_on_check": 93.90
}
Get Split Status
GET /v1/checks/{check_id}/split/status
Authorization: Bearer {access_token}
Response:
{
"check_id": "chk_abc123",
"split_status": "partial",
"original_total": 156.50,
"total_paid": 62.60,
"remaining_balance": 93.90,
"splits": [
{"split_id": "spl_001", "total": 62.60, "status": "paid", "paid_at": "2026-01-18T20:15:00Z"},
{"split_id": "spl_002", "total": 54.78, "status": "pending"},
{"split_id": "spl_003", "total": 39.12, "status": "pending"}
]
}
Cancel Split
DELETE /v1/checks/{check_id}/split
Authorization: Bearer {access_token}
Response:
{
"check_id": "chk_abc123",
"split_cancelled": true,
"restored_to_single_check": true,
"note": "All items returned to single check. Previous partial payments retained."
}
Seat-Based Operations
Assign Items to Seat
POST /v1/checks/{check_id}/seats/{seat_number}/items
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"item_ids": ["item_001", "item_005"]
}
Get Seat Summary
GET /v1/checks/{check_id}/seats
Authorization: Bearer {access_token}
Response:
{
"check_id": "chk_abc123",
"seats": [
{
"seat": 1,
"guest_name": "John",
"items": [
{"id": "item_001", "name": "Steak", "price": 45.00}
],
"subtotal": 45.00,
"tax": 4.05,
"total": 49.05,
"status": "unpaid"
},
{
"seat": 2,
"guest_name": "Jane",
"items": [
{"id": "item_002", "name": "Pasta", "price": 22.00},
{"id": "item_003", "name": "Wine", "price": 12.00}
],
"subtotal": 34.00,
"tax": 3.06,
"total": 37.06,
"status": "unpaid"
}
],
"shared_items": [
{
"id": "item_004",
"name": "Appetizer",
"price": 18.00,
"shared_by": [1, 2],
"per_seat": 9.00
}
]
}
Tip Distribution
Add Tip to Split
POST /v1/checks/{check_id}/splits/{split_id}/tip
Authorization: Bearer {access_token}
Content-Type: application/json
Request:
{
"tip_type": "percentage",
"value": 20
}
Response:
{
"split_id": "spl_001",
"subtotal": 45.00,
"tax": 4.05,
"tip": 9.00,
"total": 58.05
}
Suggested Tips
GET /v1/checks/{check_id}/splits/{split_id}/suggested-tips
Authorization: Bearer {access_token}
Response:
{
"split_id": "spl_001",
"subtotal": 45.00,
"suggestions": [
{"percentage": 15, "amount": 6.75},
{"percentage": 18, "amount": 8.10},
{"percentage": 20, "amount": 9.00},
{"percentage": 25, "amount": 11.25}
]
}
Error Codes
| Code | Message | Description |
|---|---|---|
CHECK_NOT_FOUND | Check not found | Invalid check ID |
ALREADY_SPLIT | Check already split | Cannot reinitialize |
ITEM_NOT_FOUND | Item not found | Invalid item ID |
SPLIT_PAID | Split already paid | Cannot modify paid split |
INVALID_AMOUNT | Amount exceeds balance | Custom amount too high |
PERCENTAGE_MISMATCH | Percentages must equal 100 | Invalid percentage split |
Best Practices
- Confirm with guests - Verify split preferences before processing
- Handle shared items - Ask how to distribute appetizers/shared dishes
- Show running totals - Display each person's total before payment
- Support mixed payment - Allow different payment methods per split
- Print itemized receipts - Provide detailed receipt for each split
Related Documentation
- Payments API - Payment processing
- Orders API - Order management
- Bar API - Bar and tab management