---
title: "Uploads a purchase order document"
method: POST
path: "/api/v1/purchase_orders/{id}/upload"
tags: ["Purchase Orders"]
---

# Uploads a purchase order document

`POST /api/v1/purchase_orders/{id}/upload`

## Request

- Base URL: `https://demo.invoiceninja.com`
- URL: `https://demo.invoiceninja.com/api/v1/purchase_orders/{id}/upload`
- Auth: none declared. Required headers: `X-API-TOKEN`, `X-Requested-With`
- TypeScript: <https://skmtc.dev/invoiceninja/apis/invoice-ninja-api-reference/docs/api/v1/purchase_orders/:id/upload/post.ts> (a function with typed inputs; its response is checked against the schema)

Handles the uploading of a document to a purchase_order

## Path parameters

- `id` string, string, required

## Query parameters

- `include` string

## Headers

- `X-API-TOKEN` string, required
- `X-Requested-With` string, required

## Request body `multipart/form-data`

- object
  - `_method` string
  - `documents` string[]

## Response `200`

Returns the Purchase Order object

- PurchaseOrder
  - `id` string: The unique hashed identifier for the purchase order
  - `user_id` string: The unique hashed identifier for the user who created the purchase order
  - `assigned_user_id` string: The unique hashed identifier for the user assigned to the purchase order
  - `vendor_id` string: The unique hashed identifier for the vendor associated with the purchase order
  - `status_id` string: The status of the purchase order represented by a unique identifier
  - `number` string: The unique alpha-numeric purchase order number per company
  - `quote_number` string: The quote number associated with this purchase order
  - `terms` string: The terms and conditions for the purchase order
  - `public_notes` string: Publicly visible notes associated with the purchase order
  - `private_notes` string: Privately visible notes associated with the purchase order, not disclosed to the vendor
  - `footer` string: The footer text of the purchase order
  - `custom_value1` string: First custom value field for additional information
  - `custom_value2` string: Second custom value field for additional information
  - `custom_value3` string: Third custom value field for additional information
  - `custom_value4` string: Fourth custom value field for additional information
  - `tax_name1` string: The name of the first tax applied to the purchase order
  - `tax_name2` string: The name of the second tax applied to the purchase order
  - `tax_rate1` number, float: The rate of the first tax applied to the purchase order
  - `tax_rate2` number, float: The rate of the second tax applied to the purchase order
  - `tax_name3` string: The name of the third tax applied to the purchase order
  - `tax_rate3` number, float: The rate of the third tax applied to the purchase order
  - `total_taxes` number, float: The total amount of taxes applied to the purchase order
  - `line_items` InvoiceItem[]: An array of objects which define the line items of the purchase order
    - `quantity` number: The quantity of the product offered for this line item
    - `cost` number, float: The cost of the product offered for this line item
    - `product_key` string: The product key of the product offered for this line item (Referred to as Product in the product tab)
    - `tags` string: A comma-separated snapshot of the product tag names for this line item
    - `product_cost` number, float: The cost of the product offered for this line item (Referred to as Cost in the product tab)
    - `notes` string: The notes/description for the product offered for this line item
    - `discount` number, float: The discount applied to the product offered for this line item
    - `is_amount_discount` boolean: Indicates whether the discount applied to the product offered for this line item is a fixed amount or a percentage
    - `tax_name1` string: The name of the first tax applied to the product offered for this line item
    - `tax_rate1` number, float: The rate of the first tax applied to the product offered for this line item
    - `tax_name2` string: The name of the second tax applied to the product offered for this line item
    - `tax_rate2` number, float: The rate of the second tax applied to the product offered for this line item
    - `tax_name3` string: The name of the third tax applied to the product offered for this line item
    - `tax_rate3` number, float: The rate of the third tax applied to the product offered for this line item
    - `sort_id` string: Deprecated
    - `line_total` number, float: The total amount of the product offered for this line item
    - `gross_line_total` number, float: The total amount of the product offered for this line item before discounts
    - `tax_amount` number, float: The total amount of tax applied to the product offered for this line item
    - `custom_value1` string: The first custom value of the product offered for this line item
    - `custom_value2` string: The second custom value of the product offered for this line item
    - `custom_value3` string: The third custom value of the product offered for this line item
    - `custom_value4` string: The fourth custom value of the product offered for this line item
    - `type_id` string: 1 = product, 2 = service, 3 unpaid gateway fee, 4 paid gateway fee, 5 late fee, 6 expense
    - `tax_id` string: The tax ID of the product: 1 product, 2 service, 3 digital, 4 shipping, 5 exempt, 5 reduced tax, 7 override, 8 zero rate, 9 reverse tax
  - `amount` number, float: The total amount of the purchase order before taxes and discounts
  - `balance` number, float: The balance due for the purchase order after accounting for payments
  - `paid_to_date` number, float: The total amount paid on the purchase order so far
  - `discount` number, float: The discount amount or percentage applied to the purchase order
  - `partial` number, float: The partial or deposit amount for the purchase order
  - `is_amount_discount` boolean: Boolean flag indicating if the discount is a fixed amount or a percentage
  - `is_deleted` boolean: Boolean flag indicating if the purchase order has been deleted
  - `uses_inclusive_taxes` boolean: Boolean flag indicating if the taxes used are inclusive or exclusive
  - `date` string, date: The date the purchase order was created
  - `last_sent_date` string, date: The last date the purchase order was sent to the vendor
  - `next_send_date` string, date: The next scheduled date for sending a reminder for the purchase order
  - `partial_due_date` string, date: The due date for the partial or deposit amount
  - `due_date` string, date: The due date for the total amount of the purchase order
  - `settings` CompanySettings
    - `currency_id` string, required: The default currency id
    - `timezone_id` string: The timezone id
    - `date_format_id` string: The date format id
    - `military_time` boolean: Toggles 12/24 hour time
    - `language_id` string: The language id
    - `show_currency_code` boolean: Toggles whether the currency symbol or code is shown
    - `payment_terms` integer: -1 sets no payment term, 0 sets payment due immediately, positive integers indicates payment terms in days
    - `company_gateway_ids` string: A commad separate list of available gateways
    - `custom_value1` string: A Custom Label
    - `custom_value2` string: A Custom Label
    - `custom_value3` string: A Custom Label
    - `custom_value4` string: A Custom Label
    - `default_task_rate` number, float: The default task rate
    - `send_reminders` boolean: Toggles whether reminders are sent
    - `enable_client_portal_tasks` boolean: Show/hide the tasks panel in the client portal
    - `email_style` 'plain' | 'light' | 'dark' | 'custom': options include plain,light,dark,custom
    - `reply_to_email` string, email: The reply to email address
    - `bcc_email` string: A comma separate list of BCC emails
    - `pdf_email_attachment` boolean: Toggles whether to attach PDF as attachment
    - `ubl_email_attachment` boolean: Toggles whether to attach UBL as attachment
    - `email_style_custom` string: The custom template
    - `counter_number_applied` 'when_saved' | 'when_sent' | 'when_paid': enum when the invoice number counter is set
    - `quote_number_applied` 'when_saved' | 'when_sent': enum when the quote number counter is set
    - `custom_message_dashboard` string: A custom message which is displayed on the dashboard
    - `custom_message_unpaid_invoice` string: A custom message which is displayed in the client portal when a client is viewing a unpaid invoice.
    - `custom_message_paid_invoice` string: A custom message which is displayed in the client portal when a client is viewing a paid invoice.
    - `custom_message_unapproved_quote` string: A custom message which is displayed in the client portal when a client is viewing a unapproved quote.
    - `lock_invoices` 'off' | 'when_sent' | 'when_paid' | 'end_of_month': Toggles whether invoices are locked once sent and cannot be modified further
    - `auto_archive_invoice` boolean: Toggles whether a invoice is archived immediately following payment
    - `auto_archive_quote` boolean: Toggles whether a quote is archived after being converted to a invoice
    - `auto_convert_quote` boolean: Toggles whether a quote is converted to a invoice when approved
    - `inclusive_taxes` boolean: Boolean flag determining whether inclusive or exclusive taxes are used
    - `translations` object: JSON payload of customized translations
    - `task_number_pattern` string: Allows customisation of the task number pattern
    - `task_number_counter` integer: The incrementing counter for tasks
    - `reminder_send_time` integer: Time from UTC +0 when the email will be sent to the client
    - `expense_number_pattern` string: Allows customisation of the expense number pattern
    - `expense_number_counter` integer: The incrementing counter for expenses
    - `vendor_number_pattern` string: Allows customisation of the vendor number pattern
    - `vendor_number_counter` integer: The incrementing counter for vendors
    - `ticket_number_pattern` string: Allows customisation of the ticket number pattern
    - `ticket_number_counter` integer: The incrementing counter for tickets
    - `payment_number_pattern` string: Allows customisation of the payment number pattern
    - `payment_number_counter` integer: The incrementing counter for payments
    - `invoice_number_pattern` string: Allows customisation of the invoice number pattern
    - `invoice_number_counter` integer: The incrementing counter for invoices
    - `quote_number_pattern` string: Allows customisation of the quote number pattern
    - `quote_number_counter` integer: The incrementing counter for quotes
    - `client_number_pattern` string: Allows customisation of the client number pattern
    - `client_number_counter` integer: The incrementing counter for clients
    - `credit_number_pattern` string: Allows customisation of the credit number pattern
    - `credit_number_counter` integer: The incrementing counter for credits
    - `recurring_invoice_number_prefix` string: This string is prepended to the recurring invoice number
    - `reset_counter_frequency_id` integer: CONSTANT which is used to apply the frequency which the counters are reset
    - `reset_counter_date` string, date: The explicit date which is used to reset counters
    - `counter_padding` integer: Pads the counter with leading zeros
    - `shared_invoice_quote_counter` boolean: Flags whether to share the counter for invoices and quotes
    - `update_products` boolean: Determines if client fields are updated from third party APIs
    - `convert_products` boolean
    - `fill_products` boolean: Automatically fill products based on product_key
    - `invoice_terms` string: The default invoice terms
    - `quote_terms` string: The default quote terms
    - `invoice_taxes` integer: The number of Taxes that can be applied to the invoice
    - `invoice_design_id` string: The default design id (invoice, quote etc)
    - `quote_design_id` string: The default design id (invoice, quote etc)
    - `invoice_footer` string: The default invoice footer
    - `invoice_labels` string: JSON string of invoice labels
    - `tax_rate1` number, float: The tax rate (float)
    - `tax_name1` string: The tax name
    - `tax_rate2` number, float: The tax rate (float)
    - `tax_name2` string: The tax name
    - `tax_rate3` number, float: The tax rate (float)
    - `tax_name3` string: The tax name
    - `payment_type_id` string: The default payment type id
    - `custom_fields` string: JSON string of custom fields
    - `email_footer` string: The default email footer
    - `email_sending_method` 'default' | 'gmail' | 'office365' | 'client_postmark' | 'client_mailgun' | 'mailgun' | 'client_brevo': The email driver to use to send email
    - `gmail_sending_user_id` string: The hashed_id of the user account to send email from
    - `email_subject_invoice` string
    - `email_subject_quote` string
    - `email_subject_payment` string
    - `email_template_invoice` string: The full template for invoice emails
    - `email_template_quote` string: The full template for quote emails
    - `email_template_payment` string: The full template for payment emails
    - `email_subject_reminder1` string: Email subject for Reminder
    - `email_subject_reminder2` string: Email subject for Reminder
    - `email_subject_reminder3` string: Email subject for Reminder
    - `email_subject_reminder_endless` string: Email subject for endless reminders
    - `email_template_reminder1` string: The full template for Reminder 1
    - `email_template_reminder2` string: The full template for Reminder 2
    - `email_template_reminder3` string: The full template for Reminder 3
    - `email_template_reminder_endless` string: The full template for enless reminders
    - `enable_portal_password` boolean: Toggles whether a password is required to log into the client portal
    - `show_accept_invoice_terms` boolean: Toggles whether the terms dialogue is shown to the client
    - `show_accept_quote_terms` boolean: Toggles whether the terms dialogue is shown to the client
    - `require_invoice_signature` boolean: Toggles whether a invoice signature is required
    - `require_quote_signature` boolean: Toggles whether a quote signature is required
    - `name` string: The company name
    - `company_logo` string: The company logo file
    - `website` string, uri: The company website URL
    - `address1` string: The company address line 1
    - `address2` string: The company address line 2
    - `city` string: The company city
    - `state` string: The company state
    - `postal_code` string: The company zip/postal code
    - `phone` string: The company phone
    - `email` string, email: The company email
    - `country_id` string: The country ID
    - `vat_number` string: The company VAT/TAX ID number
    - `page_size` string: The default page size
    - `font_size` number: The font size
    - `primary_font` string: The primary font
    - `secondary_font` string: The secondary font
    - `hide_paid_to_date` boolean: Flags whether to hide the paid to date field
    - `embed_documents` boolean: Toggled whether to embed documents in the PDF
    - `all_pages_header` boolean: The header for the PDF
    - `all_pages_footer` boolean: The footer for the PDF
    - `document_email_attachment` boolean: Toggles whether to attach documents in the email
    - `enable_client_portal_password` boolean: Toggles password protection of the client portal
    - `enable_email_markup` boolean: Toggles the use of markdown in emails
    - `enable_client_portal_dashboard` boolean: Toggles whether the client dashboard is shown in the client portal
    - `enable_client_portal` boolean: Toggles whether the entire client portal is displayed to the client, or only the context
    - `email_template_statement` string: The body of the email for statements
    - `email_subject_statement` string: The subject of the email for statements
    - `signature_on_pdf` boolean: Toggles whether the signature (if available) is displayed on the PDF
    - `quote_footer` string: The default quote footer
    - `email_subject_custom1` string: Custom reminder template subject
    - `email_subject_custom2` string: Custom reminder template subject
    - `email_subject_custom3` string: Custom reminder template subject
    - `email_template_custom1` string: Custom reminder template body
    - `email_template_custom2` string: Custom reminder template body
    - `email_template_custom3` string: Custom reminder template body
    - `enable_reminder1` boolean: Toggles whether this reminder is enabled
    - `enable_reminder2` boolean: Toggles whether this reminder is enabled
    - `enable_reminder3` boolean: Toggles whether this reminder is enabled
    - `num_days_reminder1` integer: The Reminder interval
    - `num_days_reminder2` integer: The Reminder interval
    - `num_days_reminder3` integer: The Reminder interval
    - `schedule_reminder1` 'after_invoice_date' | 'before_due_date' | 'after_due_date': (enum: after_invoice_date, before_due_date, after_due_date)
    - `schedule_reminder2` 'after_invoice_date' | 'before_due_date' | 'after_due_date': (enum: after_invoice_date, before_due_date, after_due_date)
    - `schedule_reminder3` 'after_invoice_date' | 'before_due_date' | 'after_due_date': (enum: after_invoice_date, before_due_date, after_due_date)
    - `late_fee_amount1` number, float: The late fee amount for reminder 1
    - `late_fee_amount2` number, float: The late fee amount for reminder 2
    - `late_fee_amount3` number, float: The late fee amount for reminder 2
    - `endless_reminder_frequency_id` string: The frequency id of the endless reminder
    - `client_online_payment_notification` boolean: Determines if a client should receive the notification for a online payment
    - `client_manual_payment_notification` boolean: Determines if a client should receive the notification for a manually entered payment
    - `enable_e_invoice` boolean: Determines if e-invoicing is enabled
    - `default_expense_payment_type_id` string: The default payment type for expenses
    - `e_invoice_type` string: The e-invoice type
    - `mailgun_endpoint` 'api.mailgun.net' | 'api.eu.mailgun.net': The mailgun endpoint - used to determine whether US or EU endpoints are used
    - `client_initiated_payments` boolean: Determines if clients can initiate payments directly from the client portal
    - `client_initiated_payments_minimum` number, float: The minimum amount a client can pay
    - `sync_invoice_quote_columns` boolean: Determines if invoice and quote columns are synced for the PDF rendering, or if they use their own columns
    - `show_task_item_description` boolean: Determines if the task item description is shown on the invoice
    - `allow_billable_task_items` boolean: Determines if task items can be marked as billable
    - `accept_client_input_quote_approval` boolean: Determines if clients can approve quotes and also pass through a PO Number reference
    - `custom_sending_email` string, email: When using Mailgun or Postmark, the FROM email address can be customized using this setting.
    - `show_paid_stamp` boolean: Determines if the PAID stamp is shown on the invoice
    - `show_shipping_address` boolean: Determines if the shipping address is shown on the invoice
    - `company_logo_size` integer: The size of the company logo on the PDF - percentage value between 0 and 100
    - `show_email_footer` boolean: Determines if the email footer is shown on emails
    - `email_alignment` 'left' | 'center' | 'right': The alignment of the email body text, options include left / center / right
    - `auto_bill_standard_invoices` boolean: Determines if standard invoices are automatically billed when they are created or due
    - `postmark_secret` string: The Postmark secret API key
    - `mailgun_secret` string: The Mailgun secret API key
    - `mailgun_domain` string: The Mailgun domain
    - `send_email_on_mark_paid` boolean: Determines if an email is sent when an invoice is marked as paid
    - `vendor_portal_enable_uploads` boolean: Determines if vendors can upload files to the portal
    - `besr_id` string: The BESR ID
    - `qr_iban` string: The IBAN for the QR code
    - `email_subject_purchase_order` string: The email subject for purchase orders
    - `email_template_purchase_order` string: The email template for purchase orders
    - `require_purchase_order_signature` boolean: Determines if a signature is required on purchase orders
    - `purchase_order_public_notes` string: The public notes for purchase orders
    - `purchase_order_terms` string: The terms for purchase orders
    - `purchase_order_footer` string: The footer for purchase orders
    - `purchase_order_design_id` string: The design id for purchase orders
    - `purchase_order_number_pattern` string: The pattern for purchase order numbers
    - `purchase_order_number_counter` integer: The counter for purchase order numbers
    - `page_numbering_alignment` 'left' | 'center' | 'right': The alignment for page numbering: options include left / center / right
    - `page_numbering` boolean: Determines if page numbering is enabled on Document PDFs
    - `auto_archive_invoice_cancelled` boolean: Determines if invoices are automatically archived when they are cancelled
    - `email_from_name` string: The FROM name for emails when using Custom emailers
    - `show_all_tasks_client_portal` 'all' | 'uninvoiced' | 'invoiced': Determines if all tasks are shown on the client portal
    - `entity_send_time` integer: The time that emails are sent. The time is localized to the clients locale, integer values from 1 - 24
    - `shared_invoice_credit_counter` boolean: Determines if the invoice and credit counter are shared
    - `reply_to_name` string: The reply to name for emails
    - `hide_empty_columns_on_pdf` boolean: Determines if empty columns are hidden on PDFs
    - `enable_reminder_endless` boolean: Determines if endless reminders are enabled
    - `use_credits_payment` boolean: Determines if credits can be used as a payment method
    - `recurring_invoice_number_pattern` string: The pattern for recurring invoice numbers
    - `recurring_invoice_number_counter` integer: The counter for recurring invoice numbers
    - `client_portal_under_payment_minimum` number, float: The minimum payment payment
    - `auto_bill_date` 'on_send_date' | 'on_due_date': Determines when the invoices are auto billed
    - `primary_color` string: The primary color for the client portal / document highlights
    - `secondary_color` string: The secondary color for the client portal / document highlights
    - `client_portal_allow_under_payment` boolean: Determines if clients can pay invoices under the invoice amount due
    - `client_portal_allow_over_payment` boolean: Determines if clients can pay invoices over the invoice amount
    - `auto_bill` 'off' | 'always' | 'optin' | 'optout': Determines how autobilling is applied for recurring invoices
    - `client_portal_terms` string: The terms which are displayed on the client portal
    - `client_portal_privacy_policy` string: The privacy policy which is displayed on the client portal
    - `client_can_register` boolean: Determines if clients can register on the client portal
    - `portal_design_id` string: The design id for the client portal
    - `late_fee_endless_percent` number, float: The late fee percentage for endless late fees
    - `late_fee_endless_amount` number, float: The late fee amount for endless late fees
    - `auto_email_invoice` boolean: Determines if invoices are automatically emailed when they are created
    - `email_signature` string: The email signature for emails
    - `classification` string: The classification for the company
    - `valid_until` string: Default validity period for quotes
    - `credit_terms` string: Default terms for credit notes
    - `credit_footer` string: Default footer for credit notes
  - `last_viewed` number: Timestamp
  - `updated_at` number: Timestamp
  - `archived_at` number: Timestamp
  - `custom_surcharge1` number, float: First custom surcharge amount for the purchase order
  - `custom_surcharge2` number, float: Second custom surcharge amount for the purchase order
  - `custom_surcharge3` number, float: Third custom surcharge amount for the purchase order
  - `custom_surcharge4` number, float: Fourth custom surcharge amount for the purchase order
  - `custom_surcharge_tax1` boolean: Boolean flag indicating if taxes are charged on the first custom surcharge amount
  - `custom_surcharge_tax2` boolean: Boolean flag indicating if taxes are charged on the second custom surcharge amount
  - `custom_surcharge_tax3` boolean: Boolean flag indicating if taxes are charged on the third custom surcharge amount
  - `custom_surcharge_tax4` boolean: Boolean flag indicating if taxes are charged on the fourth custom surcharge amount
  - `backup` string: Backup data or file reference for this purchase order
  - `client_id` string: The unique identifier of the client associated with this purchase order
  - `currency_id` string: The unique identifier of the currency
  - `design_id` string: The unique identifier of the design template used for this purchase order
  - `exchange_rate` number, float: The exchange rate used for currency conversion
  - `invoice_id` string: The unique identifier of the related invoice
  - `quote_id` string: The unique identifier of the related quote
  - `location_id` string: The unique identifier of the location
  - `po_number` string: The purchase order number
  - `project_id` string: The unique identifier of the project associated with this purchase order
  - `recurring_id` string: The unique identifier of the recurring schedule
  - `reminder1_sent` number: Timestamp when the first reminder was sent
  - `reminder2_sent` number: Timestamp when the second reminder was sent
  - `reminder3_sent` number: Timestamp when the third reminder was sent
  - `reminder_last_sent` number: Timestamp when the last reminder was sent

## Other responses

- `401`: Authentication error
- `403`: Authorization error
- `422`: Validation error
- `429`: Rate Limit Exceeded
- `5XX`: Server error
- `default`: Unexpected Error

## Changes

- **2026-09-08** `bcda1f823746`: 1 info
  - added the optional property `quote_id` to the response with the `200` status
- **2026-08-21** `a8b7a375e4ed`: 1 info
  - added the optional property `line_items/items/tags` to the response with the `200` status
- **2026-04-20** `69a36036d334`: 1 info
  - the response optional property `id` became read-only for the status `200`
- **2025-11-22** `00ad5cc89fad`: 14 info
  - added the optional property `backup` to the response with the `200` status
  - added the optional property `client_id` to the response with the `200` status
  - added the optional property `currency_id` to the response with the `200` status
  - added the optional property `design_id` to the response with the `200` status
  - …10 more
- **2025-09-26** `536b69720520`: 1 breaking, 3 warning
  - the `settings/show_all_tasks_client_portal` response's property type changed from `boolean` to `string` for status `200`
  - added the new `all` enum value to the `settings/show_all_tasks_client_portal` response property for the response status `200`
  - added the new `invoiced` enum value to the `settings/show_all_tasks_client_portal` response property for the response status `200`
  - added the new `uninvoiced` enum value to the `settings/show_all_tasks_client_portal` response property for the response status `200`

[Operation history](https://skmtc.dev/invoiceninja/apis/invoice-ninja-api-reference/changes/api/v1/purchase_orders/:id/upload/post.md)

---

[API](https://skmtc.dev/invoiceninja/apis/invoice-ninja-api-reference.md) - [All operations](https://skmtc.dev/invoiceninja/apis/invoice-ninja-api-reference/llms.txt) - [OpenAPI document](https://skmtc.dev/invoiceninja/apis/invoice-ninja-api-reference/revisions/bcda1f823746?raw)
