Add & Update Expenses

Expense parameters

Parameters Description
Notes Expense entry notes
Total-Cost integer value for the expense entry
Project-ID Valid and existing project ID
Expense-Category-ID Valid and existing expense category ID
Billable Options: true, false. Note: Only expenses that are billable can be invoiced.
Spent-At Date for expense entry
Units integer value for use with an expense calculated by unit price (Example: Mileage)

Create a new expense

POST https://YOURACCOUNT.harvestapp.com/expenses

HTTP Response: 201 Created

Note: Upon successfully creating a new expense, we’ll return a Location header which will contain the newly created expense ID.

Location/expenses/{NEW_EXPENSE_ID}

Examples

Example request in Postman

<expense>
  <notes>Your Expense</notes>
  <total-cost type="decimal">11.00</total-cost>
  <project-id type="integer">3554414</project-id>
  <expense-category-id type="integer">1338060</expense-category-id>
  <billable type="boolean">true</billable>
  <spent-at type="date">2015-04-17</spent-at>
</expense>
{
    "expense": {
        "notes": "Your Expense",
        "total_cost": 11,
        "project_id": 3554414,
        "expense_category_id": 1338060,
        "billable": true,
        "spent_at": "2015-04-17"
    }
}

To add an expense with a unit price: (Example: Mileage)

<expense>
  <notes>Mileage Expense</notes>
  <units type="integer">35</units>
  <project-id type="integer">2</project-id>
  <expense-category-id type="integer">1338061</expense-category-id>
  <billable type="boolean">true</billable>
  <spent-at type="date">2015-04-17</spent-at>
</expense>
{
    "expense": {
        "notes": "Mileage Expense",
        "units": 11,
        "project_id": 3554414,
        "expense_category_id": 1338061,
        "billable": true,
        "spent_at": "2015-04-17"
    }
}

Update an existing expense

PUT https://YOURACCOUNT.harvestapp.com/expenses/{EXPENSEID}

HTTP Response: 200 OK

Examples

Example request in Postman

<expense>
  <notes>Your Updated Expense</notes>
  <total-cost type="decimal">14.00</total-cost>
  <billable type="boolean">false</billable>
</expense>
{
    "expense": {
        "notes": "Your Updated Expense",
        "total_cost": 14,
        "billable": false
    }
}

Show an expense

GET https://YOURACCOUNT.harvestapp.com/expenses/{EXPENSEID}

Note: The has-receipt field will indicate whether a receipt image has been attached. If it is true, you can use the URL in receipt-url to fetch the image.

HTTP Response: 200 OK

Example request in Postman

<?xml version="1.0" encoding="UTF-8"?>
<expense>
    <id type="integer">7631396</id>
    <total-cost type="decimal">14.0</total-cost>
    <units type="decimal">14.0</units>
    <created-at type="dateTime">2015-04-21T14:20:34Z</created-at>
    <updated-at type="dateTime">2015-04-21T14:34:27Z</updated-at>
    <project-id type="integer">3554414</project-id>
    <expense-category-id type="integer">1338061</expense-category-id>
    <user-id type="integer">508343</user-id>
    <spent-at type="date">2015-04-17</spent-at>
    <is-closed type="boolean">false</is-closed>
    <notes>Your Updated Expense</notes>
    <invoice-id type="integer">0</invoice-id>
    <billable type="boolean">false</billable>
    <company-id type="integer">210377</company-id>
    <has-receipt type="boolean">false</has-receipt>
    <receipt-url></receipt-url>
    <is-locked type="boolean">false</is-locked>
    <locked-reason nil="true"/>
</expense>
{
    "expense": {
        "id": 7631396,
        "total_cost": 14,
        "units": 14,
        "created_at": "2015-04-21T14:20:34Z",
        "updated_at": "2015-04-21T14:34:27Z",
        "project_id": 3554414,
        "expense_category_id": 1338061,
        "user_id": 508343,
        "spent_at": "2015-04-17",
        "is_closed": false,
        "notes": "Your Updated Expense",
        "invoice_id": 0,
        "billable": false,
        "company_id": 210377,
        "has_receipt": false,
        "receipt_url": "",
        "is_locked": false,
        "locked_reason": null
    }
}

Delete an existing expense

DELETE https://YOURACCOUNT.harvestapp.com/expenses/{EXPENSEID}

HTTP Response: 200 OK

Attach receipt image

POST https://YOURACCOUNT.harvestapp.com/expenses/{EXPENSEID}/receipt

When adding or updating an image receipt, there’s no need to post any JSON or XML. Just post the image data as you would any multipart form data. Be sure to set the name of the post data to expense[receipt] and set the filename= parameter:

HTTP Response: 200 OK

User-Agent: Your Application Name
Host: YOURACCOUNT.harvestapp.com
Accept: application/xml
Authorization: Basic (insert your authentication string here)
Content-Length: (value based on request size)
Content-Type: multipart/form-data; boundary=--------------------------b7edea381b46

--------------------------b7edea381b46
Content-Disposition: form-data; name="expense[receipt]"; filename="hotel.jpg"
Content-Type: image/jpeg

BINARY IMAGE DATA

--------------------------b7edea381b46

Show a receipt image

GET https://YOURACCOUNT.harvestapp.com/expenses/{EXPENSEID}/receipt

After a successful request, we’ll return the image URL, along with HTTP Response: 200 OK

Example request in Postman

Expenses for other users

You may add an of_user={USERID} parameter to the URL of any expense tracking API call to work with the timesheet of another user. The authenticating user must be an Administrator for this to work.

Example request: GET https://YOURACCOUNT.harvestapp.com/expenses?of_user=123456

Locked expenses

Administrators may edit and delete locked expenses. The following fields are considered read-only on locked expenses: project_id, expense_category_id, spent_at.

Still have questions? We’re happy to help!

Contact Us