> ## Documentation Index
> Fetch the complete documentation index at: https://help.gorelo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Updates an invoice: its header fields, its status (approve only) and its lines.

> Every field is optional, and a field left out keeps its value. `Reference`,
`InvoiceTemplateId`, `InvoiceEmailTemplateId` and `BrandingThemeId` clear
with `null`; with no template set, the service provider's default applies.
`InvoiceDate`, `DueDate`, `StatusId` and `LineItems` are not clearable,
and `null` leaves them alone. `DueDate` may not be earlier than `InvoiceDate`.

<b>Which invoices can change.</b> Draft, Submitted and Approved, including an Approved
invoice that is part paid; if its new total falls below what has been paid,
`AmountDue` reads 0. A Paid or Void invoice is refused with 409 - reverse a payment
first; a void invoice is final.

<b>Status.</b>`StatusId` accepts only 5 (Approved), from Draft or Submitted. Approving
pushes the invoice to the connected accounting system, as the app does, and an invoice
whose total is 0 is recorded as Paid instead - check `Status` on the response. To mark
an invoice paid use `POST /v1/payments`; to void or delete it, `DELETE`.

<b>Lines.</b> Sending `LineItems` replaces the set, matched by line `Id`, so send
every line you want to keep (at most 100). An entry with an `Id` on this invoice is
updated in place and a field left out of it is kept; an entry with no `Id` is a new
line, needing `ItemId` and `Quantity`, with the same fallbacks to the item as
`POST /v1/invoices`; an existing line left out is removed, and the time, ticket charge
or contract charge it billed goes back to waiting to be invoiced. A bundle line's
`Id` acts on the whole bundle. On a line billing a time entry `Quantity` can't
change, and a new price or billable status carries through to the time entry. On a line,
`Description` and `CoaCode` clear with `null` and `TaxId: null` means
no tax. A line that isn't Billable bills 0. Line amounts, tax and the invoice totals are
calculated, never accepted.


Returns the invoice in the `GET /v1/invoices/{invoiceId}` shape. Re-sending values
the invoice already holds changes nothing.




## OpenAPI

````yaml /api-reference/openapi.json patch /v1/invoices/{invoiceId}
openapi: 3.0.4
info:
  title: Public API
  description: Gorelo Public API documentation.
  version: 1.0.0
servers:
  - url: https://api.usw.gorelo.io
    description: US
  - url: https://api.aue.gorelo.io
    description: Australia
security:
  - ApiKeyAuth: []
tags:
  - name: Attachments
    description: "Uploading a file, for anything that can carry one. One endpoint rather than one per record\r\ntype, because the upload itself is identical - only the record it is checked against differs."
  - name: Alerts
    description: Alerts management operations
  - name: Assets
    description: Assets management operations
  - name: Billing
    description: Billing management operations
  - name: Tickets
    description: Tickets management operations
  - name: Clients
    description: Clients management operations
  - name: Contacts
    description: Contacts management operations
  - name: Deletions
    description: Deletions management operations
  - name: Documents
    description: Documents management operations
  - name: Forms
    description: Forms management operations
  - name: Organization
    description: Organization management operations
  - name: Projects
    description: Projects management operations
paths:
  /v1/invoices/{invoiceId}:
    patch:
      tags:
        - Billing
      summary: >-
        Updates an invoice: its header fields, its status (approve only) and its
        lines.
      description: "Every field is optional, and a field left out keeps its value. `Reference`,\r\n`InvoiceTemplateId`, `InvoiceEmailTemplateId` and `BrandingThemeId` clear\r\nwith `null`; with no template set, the service provider's default applies.\r\n`InvoiceDate`, `DueDate`, `StatusId` and `LineItems` are not clearable,\r\nand `null` leaves them alone. `DueDate` may not be earlier than `InvoiceDate`.\r\n\n<b>Which invoices can change.</b> Draft, Submitted and Approved, including an Approved\r\ninvoice that is part paid; if its new total falls below what has been paid,\r\n`AmountDue` reads 0. A Paid or Void invoice is refused with 409 - reverse a payment\r\nfirst; a void invoice is final.\r\n\n<b>Status.</b>`StatusId` accepts only 5 (Approved), from Draft or Submitted. Approving\r\npushes the invoice to the connected accounting system, as the app does, and an invoice\r\nwhose total is 0 is recorded as Paid instead - check `Status` on the response. To mark\r\nan invoice paid use `POST /v1/payments`; to void or delete it, `DELETE`.\r\n\n<b>Lines.</b> Sending `LineItems` replaces the set, matched by line `Id`, so send\r\nevery line you want to keep (at most 100). An entry with an `Id` on this invoice is\r\nupdated in place and a field left out of it is kept; an entry with no `Id` is a new\r\nline, needing `ItemId` and `Quantity`, with the same fallbacks to the item as\r\n`POST /v1/invoices`; an existing line left out is removed, and the time, ticket charge\r\nor contract charge it billed goes back to waiting to be invoiced. A bundle line's\r\n`Id` acts on the whole bundle. On a line billing a time entry `Quantity` can't\r\nchange, and a new price or billable status carries through to the time entry. On a line,\r\n`Description` and `CoaCode` clear with `null` and `TaxId: null` means\r\nno tax. A line that isn't Billable bills 0. Line amounts, tax and the invoice totals are\r\ncalculated, never accepted.\r\n\n\r\nReturns the invoice in the `GET /v1/invoices/{invoiceId}` shape. Re-sending values\r\nthe invoice already holds changes nothing.\r\n"
      operationId: patch_v1_invoices_invoiceId
      parameters:
        - name: invoiceId
          in: path
          description: Invoice identifier.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Fields to change.
        content:
          application/json-patch+json:
            schema:
              $ref: '#/components/schemas/UpdateInvoiceCommand'
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateInvoiceCommand'
          text/json:
            schema:
              $ref: '#/components/schemas/UpdateInvoiceCommand'
          application/*+json:
            schema:
              $ref: '#/components/schemas/UpdateInvoiceCommand'
      responses:
        '200':
          description: OK
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/InvoiceDetailModelBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceDetailModelBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/InvoiceDetailModelBaseResponse'
        '400':
          description: Bad Request
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
        '401':
          description: Unauthorized
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
        '404':
          description: Not Found
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
        '409':
          description: Conflict
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
        '500':
          description: Internal Server Error
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/ObjectBaseResponse'
components:
  schemas:
    UpdateInvoiceCommand:
      type: object
      properties:
        StatusId:
          type: integer
          description: "5 (Approved) is the only value accepted, from Draft or Submitted. Approving pushes the\r\ninvoice to the connected accounting system, as approving it in the app does. An invoice\r\nwhose total is 0 is recorded as Paid instead. Sending 5 for an invoice that is already\r\nApproved changes nothing. Not clearable."
          format: int32
          nullable: true
          example: 5
        InvoiceDate:
          type: string
          description: Date of issue, a calendar date. Not clearable.
          format: date-time
          nullable: true
          example: '2026-09-15T00:00:00.0000000+00:00'
        DueDate:
          type: string
          description: >-
            Date payment is due, a calendar date. May not be earlier than
            InvoiceDate. Not clearable.
          format: date-time
          nullable: true
          example: '2026-10-15T00:00:00.0000000+00:00'
        Reference:
          type: string
          description: Free-text reference. Send null to clear it.
          nullable: true
          example: PO-4471-REV
        InvoiceTemplateId:
          type: integer
          description: >-
            PDF template for this invoice. Send null to clear it; the service
            provider's default then applies.
          format: int64
          nullable: true
          example: 12
        InvoiceEmailTemplateId:
          type: integer
          description: >-
            Email template for this invoice. Send null to clear it; the service
            provider's default then applies.
          format: int64
          nullable: true
          example: 4
        BrandingThemeId:
          type: string
          description: >-
            Branding theme the synced copy carries in the connected accounting
            system. Send null to clear it.
          format: uuid
          nullable: true
        LineItems:
          type: array
          items:
            $ref: '#/components/schemas/UpdateInvoiceLineItem'
          description: "Replaces the invoice's lines, matched by line Id. An entry with an Id on this invoice is\r\nupdated in place; an entry with no Id is added; an existing line left out is removed, and\r\nwork it was billing (a time entry, a ticket charge, a prorated contract charge) goes back\r\nto waiting to be invoiced. A bundle line's Id acts on the whole bundle. An empty array is\r\nrejected. Omit the field to leave the lines alone."
          nullable: true
      additionalProperties: false
      description: "Partial update of an invoice. Every field is optional: a field left out keeps its value. A\r\nclearable field clears with `null`."
    InvoiceDetailModelBaseResponse:
      type: object
      properties:
        StatusCode:
          $ref: '#/components/schemas/HttpStatusCode'
        IsSuccess:
          type: boolean
        Data:
          $ref: '#/components/schemas/InvoiceDetailModel'
        DataContext:
          type: object
          additionalProperties: false
          nullable: true
          example: null
        Notifications:
          type: array
          items:
            $ref: '#/components/schemas/Error'
      additionalProperties: false
    ObjectBaseResponse:
      type: object
      properties:
        StatusCode:
          $ref: '#/components/schemas/HttpStatusCode'
        IsSuccess:
          type: boolean
        Data:
          nullable: true
        DataContext:
          $ref: '#/components/schemas/ErrorDataContext'
        Notifications:
          type: array
          items:
            $ref: '#/components/schemas/Error'
      additionalProperties: false
    UpdateInvoiceLineItem:
      type: object
      properties:
        Id:
          type: string
          description: >-
            The line to update, as returned on GET /v1/invoices/{invoiceId}.
            Omit to add a new line.
          format: uuid
          nullable: true
        ItemId:
          type: string
          description: >-
            Catalog item a new line bills. Required on a new line; not accepted
            on an existing one.
          format: uuid
          nullable: true
        Quantity:
          type: number
          description: "Quantity billed, greater than 0. Required on a new line. Can't be changed on a line\r\nbilling a time entry - the hours belong to the time entry."
          format: double
          nullable: true
          example: 2
        UnitPrice:
          type: number
          description: Unit price. Falls back to the item's own price on a new line.
          format: double
          nullable: true
          example: 150
        UnitCost:
          type: number
          description: Unit cost. Falls back to the item's own cost on a new line.
          format: double
          nullable: true
          example: 90
        DiscountPercent:
          type: number
          description: Discount percentage for this line, 0-100.
          format: double
          nullable: true
          example: 5
        BillableStatusId:
          type: integer
          description: >-
            Billable status: 1 = Billable, 2 = No charge, 3 = Non-billable. A
            line that isn't billable bills 0.
          format: int32
          nullable: true
        Description:
          type: string
          description: >-
            Description shown on the invoice for this line. Send null to clear
            it.
          nullable: true
        TaxId:
          type: integer
          description: >-
            Tax applied to this line. Null, or left out on a new line, gives the
            tax the app would: the item's own tax, else the tenant default (with
            advanced tax, a tax-exempt rate or the client's tax first). Left out
            on an existing line, its tax is kept. To bill no tax, send the
            tax-exempt rate's id.
          format: int64
          nullable: true
        CoaCode:
          type: string
          description: >-
            Chart-of-accounts code. Send null to clear it. A new line falls back
            to the item's own code when this is left out.
          nullable: true
      additionalProperties: false
      description: One line on an invoice update.
    HttpStatusCode:
      enum:
        - 100
        - 101
        - 102
        - 103
        - 200
        - 201
        - 202
        - 203
        - 204
        - 205
        - 206
        - 207
        - 208
        - 226
        - 300
        - 301
        - 302
        - 303
        - 304
        - 305
        - 306
        - 307
        - 308
        - 400
        - 401
        - 402
        - 403
        - 404
        - 405
        - 406
        - 407
        - 408
        - 409
        - 410
        - 411
        - 412
        - 413
        - 414
        - 415
        - 416
        - 417
        - 421
        - 422
        - 423
        - 424
        - 426
        - 428
        - 429
        - 431
        - 451
        - 500
        - 501
        - 502
        - 503
        - 504
        - 505
        - 506
        - 507
        - 508
        - 510
        - 511
      type: integer
      format: int32
    InvoiceDetailModel:
      type: object
      properties:
        Id:
          type: string
          description: Identifier of the invoice.
          format: uuid
          example: 3f1a9e2b-6c4d-4e2a-8b1a-0e2f7c9d1a44
        Number:
          type: integer
          description: The bare sequential invoice number, prefix and suffix stripped.
          format: int64
          nullable: true
          example: 1042
        DisplayNumber:
          type: string
          description: >-
            Human-readable invoice number, including the service provider's
            configured prefix/suffix.
          example: INV-1042
        ClientId:
          type: integer
          description: Client the invoice is billed to.
          format: int64
          example: 88
        ContractId:
          type: integer
          description: "Contract this invoice was raised from, or null. A manual invoice created through\r\n`POST /v1/invoices` always has no contract — `ContractId` is accepted only on\r\ncontract-generated invoices, which this surface does not create."
          format: int64
          nullable: true
          example: 4021
        Status:
          $ref: '#/components/schemas/CodeModel'
        InvoiceDate:
          type: string
          description: >-
            Date the invoice was raised, a calendar date in the service
            provider's terms.
          format: date
          example: '2026-09-01'
        DueDate:
          type: string
          description: >-
            Date payment is due, a calendar date. Never earlier than
            InvoiceDate.
          format: date
          nullable: true
          example: '2026-10-01'
        SubTotal:
          type: number
          description: Sum of the invoice's line items before discount and tax.
          format: double
          example: 1200
        TotalDiscount:
          type: number
          description: Total discount amount across the invoice's line items.
          format: double
          example: 60
        TotalTax:
          type: number
          description: Total tax across the invoice's line items.
          format: double
          example: 85.5
        Total:
          type: number
          description: 'Grand total: SubTotal - TotalDiscount + TotalTax.'
          format: double
          example: 1225.5
        AmountPaid:
          type: number
          description: >-
            Amount paid against this invoice so far. Computed live from recorded
            payments.
          format: double
          example: 500
        AmountDue:
          type: number
          description: >-
            Amount still owed: Total - AmountPaid. Never negative on the wire; a
            credit is reported as 0.
          format: double
          example: 725.5
        Reference:
          type: string
          description: Free-text reference on the invoice, or null when not set.
          nullable: true
          example: PO-4471
        ExternalId:
          type: string
          description: >-
            Identifier of this invoice in the connected external accounting
            system (Xero or QuickBooks), or null when not yet synced.
          nullable: true
        PaymentLink:
          type: string
          description: >-
            Hosted payment link for this invoice, or null when none has been
            generated.
          nullable: true
        InvoiceTemplateId:
          type: integer
          description: Invoice template used to render this invoice's PDF.
          format: int64
          nullable: true
        InvoiceEmailTemplateId:
          type: integer
          description: Email template used when this invoice is sent.
          format: int64
          nullable: true
        BrandingThemeId:
          type: string
          description: Branding theme applied in the connected accounting system.
          format: uuid
          nullable: true
        IsEmailSent:
          type: boolean
          description: Whether this invoice has been emailed to the client.
        EmailSentOn:
          type: string
          description: When this invoice was last emailed, in UTC, or null if never.
          format: date-time
          nullable: true
        CreatedOn:
          type: string
          description: When the invoice was created, in UTC.
          format: date-time
          nullable: true
        UpdatedOn:
          type: string
          description: >-
            When the invoice was last changed, in UTC. Null when it has never
            been changed.
          format: date-time
          nullable: true
        Description:
          type: string
          description: >-
            Description on the invoice itself, separate from its lines'
            descriptions. Null when not set.
          nullable: true
        Attachments:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceAttachmentModel'
          description: Files attached to the invoice. Empty when there are none.
        LineItems:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItemModel'
          description: The invoice's line items, in the order they appear on the invoice.
        Payments:
          type: array
          items:
            $ref: '#/components/schemas/InvoicePaymentModel'
          description: "Payments recorded against the invoice, oldest first - whether recorded in Gorelo, through\r\n`POST /v1/payments`, or synced from a connected accounting system. Empty when there are\r\nnone."
      additionalProperties: false
      description: >-
        An invoice with its line items, returned by `GET
        /v1/invoices/{invoiceId}`.
    Error:
      type: object
      properties:
        Code:
          pattern: ^[0-9]{6}$
          type: string
          description: 6-digit MMTTNN error code. See the Public API error-code registry.
          example: '070101'
        Message:
          type: string
        PropertyName:
          type: string
          nullable: true
        ActionHint:
          type: string
          nullable: true
        DocUrl:
          type: string
          nullable: true
      additionalProperties: false
    ErrorDataContext:
      type: object
      properties:
        TraceId:
          type: string
          description: Request correlation id. Quote this when reporting a problem.
          nullable: true
      additionalProperties: false
      description: "The `DataContext` of an error response: carries the correlation id for the failed\r\nrequest."
    CodeModel:
      type: object
      properties:
        Id:
          type: integer
          description: >-
            Numeric identifier of the coded value (e.g. status, priority, type,
            or source id).
          format: int64
          example: 1
        Name:
          type: string
          description: Display name of the coded value.
      additionalProperties: false
      description: >-
        A coded value, such as a status, priority, type or source, as an id and
        a display name.
    InvoiceAttachmentModel:
      type: object
      properties:
        Name:
          type: string
          description: File name.
          example: timesheet-august.pdf
        Url:
          type: string
          description: >-
            Temporary secure download link. Expires, so don't store it - fetch
            the invoice again for a fresh one.
      additionalProperties: false
      description: A file attached to an invoice.
    InvoiceLineItemModel:
      type: object
      properties:
        Id:
          type: string
          description: "Identifier of the line. On a bundle line it identifies the bundle as a whole, not any one of\r\nits parts."
          format: uuid
        ItemId:
          type: string
          description: "The item charged on this line, resolving against `GET /v1/items` - the bundle itself on\r\na bundle line. Null only on an older line stored with no linked item."
          format: uuid
          nullable: true
          example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
        ItemType:
          $ref: '#/components/schemas/CodeModel'
        Name:
          type: string
          description: Name of the line as charged.
          example: Onboarding Pack
        Description:
          type: string
          description: Description of the line as charged. Null when not set.
          nullable: true
        Quantity:
          type: number
          description: Quantity billed.
          format: double
          example: 2
        UnitCost:
          type: number
          description: Unit cost of the line.
          format: double
          nullable: true
          example: 90
        UnitPrice:
          type: number
          description: Unit price charged.
          format: double
          example: 150
        DiscountPercent:
          type: number
          description: Discount percentage applied to this line, 0-100.
          format: double
          example: 10
        Tax:
          $ref: '#/components/schemas/CodeModel'
        Amount:
          type: number
          description: Line total after discount, before tax.
          format: double
          example: 270
        TaxAmount:
          type: number
          description: Tax on this line.
          format: double
        BillableStatus:
          $ref: '#/components/schemas/CodeModel'
        CoaCode:
          type: string
          description: Chart-of-accounts code the line posts to.
          nullable: true
        SubItems:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineSubItemModel'
          description: "The parts inside a bundle line, each resolving against `GET /v1/items`. Empty on every\r\nother line, never null. Returned whether or not the bundle prints its parts on the PDF."
      additionalProperties: false
      description: "One line on an invoice. A bundle is one line: its quantity, price, cost, amount and tax belong\r\nto the bundle as a whole, and `SubItems` lists what is inside it."
    InvoicePaymentModel:
      type: object
      properties:
        Id:
          type: string
          description: "Identifier of the payment. A payment recorded through `POST /v1/payments` can be removed\r\nwith `DELETE /v1/payments/{paymentId}`."
          format: uuid
          example: 8c2d4f1a-3b5e-4c7d-9a1f-2e6b8d0c4f13
        Amount:
          type: number
          description: Amount of the payment applied to this invoice.
          format: double
          example: 250
        PaymentDate:
          type: string
          description: >-
            Date the payment was received, a calendar date in the service
            provider's time zone.
          format: date
          example: '2026-10-01'
        Reference:
          type: string
          description: >-
            Reference recorded with the payment, such as a bank transaction or
            remittance number.
          example: BANK-20261001-118
      additionalProperties: false
      description: A payment recorded against an invoice.
    InvoiceLineSubItemModel:
      type: object
      properties:
        ItemId:
          type: string
          description: The part's item, resolving against `GET /v1/items`.
          format: uuid
        Name:
          type: string
          description: Name of the part as charged.
      additionalProperties: false
      description: >-
        One part inside a bundle line. Priced as part of the bundle, so it
        carries no price of its own.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      description: >-
        Your Gorelo API key. See [Generate API key](/generate-api-key). If your
        data is hosted in Australia, click the base URL at the top of this page
        and select `https://api.aue.gorelo.io`.
      name: X-API-Key
      in: header

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.