Invoice Import Restore Flow
Use these endpoints when the user previews an invoice, edits the lines on the UI, and later wants to restore that unfinished work.
1. Create Preview Session
POST /api/invoice-import/preview/
Request:
curl --request POST \
--url http://localhost:8000/api/invoice-import/preview/ \
--header 'Authorization: Bearer <access_token>' \
--form 'document=@/path/to/invoice.jpg' \
--form 'inventory_id=12' \
--form 'storage_box_id=44' \
--form 'product_family_name=Groceries'
Response:
{
"status": "success",
"mode": "preview",
"message": "Invoice parsed successfully. Review and confirm before apply.",
"session_id": 91,
"session_status": "previewed",
"invoice": {
"vendor_name": "Fresh Mart Wholesale",
"invoice_number": "INV-2026-00481",
"invoice_date": "2026-03-30",
"currency": "INR"
},
"inventory_id": 12,
"inventory_name": "Main Store",
"storage_id": 44,
"storage_box_id": 44,
"storage_box_name": "Rack A",
"storage_name": "Rack A",
"product_family_name": "Groceries",
"lines": [],
"summary": {
"total_lines": 2,
"ready_to_apply": 1,
"needs_review": 1
}
}
Save session_id on the client.
2. Save Reviewed State While Applying
POST /api/invoice-import/bulk-store/
Request:
{
"session_id": 91,
"product_family_name": "Groceries",
"lines": [
{
"line_number": 1,
"product_id": 301,
"product_name": "Aashirvaad Atta",
"selected_quantity": "2",
"inventory_id": 12,
"storage_box_id": 44
}
]
}
Success response:
{
"status": "success",
"message": "Bulk invoice lines stored successfully.",
"session_id": 91,
"session_status": "applied",
"results": [],
"summary": {
"total_lines": 1,
"processed_lines": 1,
"skipped_lines": 0,
"created_products": 0,
"existing_products": 1,
"created_inventory_items": 0,
"updated_inventory_items": 1
}
}
Failure response:
{
"status": "error",
"message": "Bulk store aborted. No changes were written.",
"errors": [
{
"line_number": 1,
"field": "selected_quantity",
"message": "Quantity must be a whole number."
}
]
}
Even on failure, the session is updated on the server with the failed attempt details.
3. Restore Latest Session
GET /api/invoice-import/sessions/latest/
Response:
{
"status": "success",
"session": {
"id": 91,
"status": "failed",
"profile_type": "self",
"team_id": null,
"last_step": "bulk-store",
"invoice": {
"vendor_name": "Fresh Mart Wholesale",
"invoice_number": "INV-2026-00481",
"invoice_date": "2026-03-30",
"currency": "INR"
},
"location": {
"inventory_id": 12,
"inventory_name": "Main Store",
"storage_id": 44,
"storage_box_id": 44,
"storage_box_name": "Rack A",
"storage_name": "Rack A"
},
"preview_lines": [],
"bulk_lines": [],
"summary": {
"total_lines": 1
},
"result_payload": {},
"error_payload": {
"message": "Bulk store aborted. No changes were written.",
"errors": [
{
"line_number": 1,
"field": "selected_quantity",
"message": "Quantity must be a whole number."
}
]
}
}
}
4. List History
GET /api/invoice-import/sessions/?limit=10
Response:
{
"status": "success",
"count": 2,
"results": [
{
"id": 91,
"status": "failed",
"profile_type": "self",
"team_id": null,
"last_step": "bulk-store",
"product_family_name": "Groceries",
"source_files": [
{
"name": "invoice.jpg",
"size": 182331,
"content_type": "image/jpeg"
}
],
"invoice_number": "INV-2026-00481",
"vendor_name": "Fresh Mart Wholesale",
"inventory_id": 12,
"inventory_name": "Main Store",
"storage_box_id": 44,
"storage_box_name": "Rack A",
"total_lines": 2
}
]
}
5. Get One Session By Id
GET /api/invoice-import/sessions/91/
Use this when the client already saved a specific session_id and wants the exact stored state back.