API Documentation

Time Tracking

Extended REST API
Clients
Projects
Tasks
People
Expenses
Expense Tracking
User Assignment
Task Assignment
Reports
Invoices
Invoice Messages
Invoice Payments
Invoice Categories


Questions?
Email support@getharvest.com

Invoices

Important: this assumes invoice feature is enabled for your account.


Show recently issued invoices

GET /invoice

HTTP Response: 200 Success
<?xml version="1.0" encoding="UTF-8"?>
<invoices type="array">
  <invoice>
    <id type="integer">8</id>
    <amount type="decimal">1155.0</amount>
    <due-amount type="decimal">0.0</due-amount>
    <due-at type="date">2008-02-06</due-at>
    <!-- human representation for due at -->
    <due-at-human-format>due upon receipt</due-at-human-format>
    <!-- invoiced period, present for generated invoices -->
    <period-end type="date" nil="true"></period-end>
    <period-start type="date" nil="true"></period-start>
    <client-id type="integer">46066</client-id>
    <!-- see  -->
    <currency>United States Dollars - USD</currency>
    <issued-at type="date">2008-02-06</issued-at>
    <notes></notes>
    <number>8008</number>
    <purchase-order></purchase-order>
    <state>paid</state>
    <!-- applied tax percentage, blank if not taxed -->
    <tax type="decimal" nil="true"></tax>
    <!-- the total tax amount -->
    <tax-amount type="decimal" nil="true"></tax-amount>
    <updated-at type="datetime">2008-04-09T12:07:56Z</updated-at>
    <created-at type="datetime">2008-04-09T12:07:56Z</created-at>
  </invoice>
  <!-- .... -->
</invoices>

For performance reasons line item data is not shown for this call, you'll have to use a more specific API call.


By default Harvest will display 50 records per page. You can get further pages by passing in a page parameter.

GET /invoice?page=2

HTTP Response: 200 Success

You can also query invoices by timeframe based on issue date.

GET /invoice?from=YYYYMMDD&to=YYYYMMDD

HTTP Response: 200 Success

Filtering by invoice state is also possible, for example this would return partially paid invoices:

GET /invoice?state=partial

HTTP Response: 200 Success

Other parameters for filtering by state are:

open
sent to the client but no payment recieved.
partial
partial payment was recorded
draft
harvest did not sent this to a client, nor recorded any payments
paid
invoice payed in full
unpaid
Macro used to return unpaid invoices
pastdue
Macro used to return past due invoices

You can also filter by client, for example to show only the invoices belonging to client with the id 23445

GET /invoice?client=23445

HTTP Response: 200 Success

All of the above filters can be combined, allowing for powerful queries into your records.

Show a particular invoice

GET /invoice/#{invoice_id}

HTTP Response: 200 Success
<?xml version="1.0" encoding="UTF-8"?>
<invoice>
  <amount type="decimal">253.44</amount>
  <client-id type="integer">8</client-id>
  <created-at type="datetime">2008-04-09T12:07:56Z</created-at>
  <currency>United States Dollars - USD</currency>
  <due-amount type="decimal">253.44</due-amount>
  <due-at type="date">2008-02-06</due-at>
  <due-at-human-format>due upon receipt</due-at-human-format>
  <id type="integer">1421</id>
  <issued-at type="date">2008-02-06</issued-at>
  <notes>Some notes go here</notes>
  <number>82208</number>
  <period-end type="date">2008-03-31</period-end>
  <period-start type="date">2007-06-26</period-start>
  <purchase-order nil="true"></purchase-order>
  <state>draft</state>
  <updated-at type="datetime">2008-04-09T18:56:51Z</updated-at>
  <!-- Line items in CSV format -->
  <csv-line-items>kind,description,quantity,unit_price,amount,taxed,project_id
Service,Security support / Apply server upgrades,0.68,80.00,54.4,true,3
Service,Security support / Install intrussion detection,0.57,80.00,45.6,true,3
Service,Backend Programming / forum admin,1.20,80.00,96.0,true,3
  </csv-line-items>
  <!-- applied a 10% tax on all line items marked as taxed -->
  <tax type="decimal" nil="true">10</tax>
  <!-- total tax amount -->
  <tax-amount type="decimal" nil="true">23.04</tax-amount>
</invoice>

Create a new invoice

POST /invoice

HTTP Response: 201 Created
Location: /invoice/#{new_id}

Sample post:

<?xml version="1.0" encoding="UTF-8"?>
<invoice>
  <due-at type="date">2008-02-06</due-at>
  <!-- human representation for due at -->
  <due-at-human-format>due upon receipt</due-at-human-format>
  <client-id type="integer">8</client-id>
  <!-- see list bellow for accepted values -->
  <currency>United States Dollars - USD</currency>
  <issued-at type="date">2008-02-06</issued-at>
  <notes>Some notes go here</notes>
  <number>82208</number>
  <!-- allowed values:
    free_form: creates a free form invoice (non-generated). Content is added via CSV.
    project: gathers content from Harvest grouping by projects
    task: gathers content from Harvest grouping by task
    people: gathers content from Harvest grouping by people
    detailed: includes detailed notes -->
  <kind>project</kind>
  <!-- comma separated project ids to gather data from, useless on
  free_form invoices -->
  <projects-to-invoice>3</projects-to-invoice>
  <!-- import hours useless on free_form invoices -->
  <import-hours>yes</import-hours>
  <!-- import expenses useless on free_form invoices -->
  <import-expenses>yes</import-expenses>
  <!-- invoiced period, present for generated invoices -->
  <period-end type="date">2008-03-31</period-end>
  <period-start type="date">2007-06-26</period-start>
  <!-- invoiced period for expenses, present for generated invoices -->
  <expense-period-end type="date">2008-03-31</expense-period-end>
  <expense-period-start type="date">2007-06-26</expense-period-start>
  <updated-at type="datetime">2008-04-09T12:07:56Z</updated-at>
  <created-at type="datetime">2008-04-09T12:07:56Z</created-at>
</invoice>

Note: we accept only a limited set of values for the currency attribute.

You can also create a free form invoice with line items by passing in the csv-line-items attribute.

Sample post:

<?xml version="1.0" encoding="UTF-8"?>
<invoice>
  <due-at type="date">2008-02-06</due-at>
  <due-at-human-format>due upon receipt</due-at-human-format>
  <client-id type="integer">8</client-id>
  <currency>United States Dollars - USD</currency>
  <issued-at type="date">2008-02-06</issued-at>
  <notes>Some notes go here</notes>
  <number>82208</number>
  <kind>free_form</kind>
  <!-- Line items in CSV format -->
  <csv-line-items>kind,description,quantity,unit_price,amount,taxed,project_id
Service,Security support / Apply server upgrades,0.68,80.00,54.4,false,3
Service,Security support / Install intrussion detection,0.57,80.00,45.6,false,3
Service,Backend Programming / forum admin,1.20,80.00,96.0,false,3
  </csv-line-items>
</invoice>

Update an existing invoice

PUT /invoice/#{invoice_id}

HTTP Response: 200 OK
Location: /invoice/#{invoice_id}

Sample put:

<?xml version="1.0" encoding="UTF-8"?>
<invoice>
  <due-at type="date">2008-02-06</due-at>
  <!-- human representation for due at -->
  <due-at-human-format>due upon receipt</due-at-human-format>
  <client-id type="integer">8</client-id>
  <!-- see list bellow for accepted values -->
  <currency>United States Dollars - USD</currency>
  <issued-at type="date">2008-02-06</issued-at>
  <notes>Some notes go here</notes>
  <number>82208</number>
</invoice>

You can also update the line items for the invoice by passing in the csv-line-items attribute.

Sample post:

<?xml version="1.0" encoding="UTF-8"?>
<invoice>
  <!-- if you don't know the project id, you can just leave it of from
  data rows ending the row with a comma. CSV header must allways be
  intact though, or updates will be discarded. -->
  <csv-line-items>kind,description,quantity,unit_price,amount,project_id
Service,Branding for marketing pages,20,100.00,2000,3
Service,What's in a name,8,100.00,800,3
  </csv-line-items>
</invoice>

Not all attributes need to be passed in, Harvest supports selective updates.


Delete existing invoice

DELETE /invoice/#{invoice_id}

HTTP Response: 200 OK.