Back to API Docs

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.