Invoices

Invoices are supplier invoices captured by an external AP-automation provider (Yooz, etc.), normalized into a canonical shape, and reconciled against tickets. All endpoints are provider-agnostic and are served on jarvis.bob-desk.com.

Properties

  • Name
    id
    Type
    string
    Description

    Unique identifier for the invoice.

  • Name
    client
    Type
    string
    Description

    Client/tenant id the invoice belongs to.

  • Name
    connection
    Type
    string
    Description

    Provider connection id that delivered this invoice.

  • Name
    provider
    Type
    string
    Description

    Name of the AP provider, e.g. "yooz".

  • Name
    externalId
    Type
    string
    Description

    Provider-side invoice id used as an idempotency key (also referred to as invoicePlatformId).

  • Name
    supplier
    Type
    object
    Description

    Provider-side supplier record.

    • externalId (provider supplier id)
    • name (supplier display name)
    • siret (SIRET number)
    • siren (SIREN number)
    • iban (IBAN for payment)
  • Name
    supplierId
    Type
    string (optional)
    Description

    Resolved Bob contractor id — populated only when the supplier has been matched.

  • Name
    ticket
    Type
    string (optional)
    Description

    Linked ticket id once the invoice has been reconciled.

  • Name
    number
    Type
    string
    Description

    Supplier-issued invoice number.

  • Name
    issueDate
    Type
    string => ISODate
    Description

    Date the invoice was issued by the supplier.

  • Name
    dueDate
    Type
    string => ISODate (optional)
    Description

    Payment due date.

  • Name
    currency
    Type
    string
    Description

    ISO 4217 currency code, e.g. "EUR".

  • Name
    amounts
    Type
    object
    Description

    Invoice totals.

    • ht (amount excluding VAT)
    • tva (VAT amount)
    • ttc (amount including VAT)
  • Name
    vatBreakdown
    Type
    array
    Description

    Per-rate VAT breakdown. Each entry contains:

    • rate (VAT rate as a decimal, e.g. 0.20)
    • base (taxable base amount)
    • amount (VAT amount for this rate)
  • Name
    lines
    Type
    array (optional)
    Description

    Invoice line items. Each entry contains:

    • label (line description)
    • qty (quantity)
    • unitPrice (unit price excluding VAT)
    • ht (line total excluding VAT)
    • vatRate (applicable VAT rate)
  • Name
    document
    Type
    object (optional)
    Description

    Attached document metadata.

    • mime (MIME type, e.g. "application/pdf")
    • ref (storage reference/URL)
    • hash (SHA-256 content hash)
  • Name
    providerStatus
    Type
    string
    Description

    Raw status string as returned by the provider.

  • Name
    matchHints
    Type
    object
    Description

    Free-text references extracted from the invoice to assist matching.

    • poRef (purchase order reference)
    • ticketRef (ticket reference found in the invoice)
    • orderRef (order reference)
  • Name
    state
    Type
    string enum
    Description

    Normalized lifecycle state of the invoice.

    • received (raw payload stored)
    • normalized (mapped to canonical shape)
    • supplier_matched (supplier resolved to a Bob contractor)
    • supplier_unmatched (supplier could not be resolved)
    • ticket_matched (linked to a ticket candidate)
    • ticket_unmatched (no ticket match found — enters manual queue)
    • linked (operator confirmed the ticket link)
    • feedback_pending (feedback being prepared for the provider)
    • feedback_sent (provider notified of the reconciliation outcome)
    • done (fully processed)
    • error (processing error, see provider logs)
    • manual_review (flagged for manual review)
  • Name
    createdAt
    Type
    string => ISODate
    Description

    Date the invoice record was created in Bob.

  • Name
    updatedAt
    Type
    string => ISODate
    Description

    Date the invoice record was last updated.


GET/invoices

List unmatched invoices

Returns the fixed manual-reconciliation queue — all invoices currently in state ticket_unmatched (i.e. invoices that could not be auto-matched to a ticket). There is no state filter: the queue content is determined by the pipeline, not by the caller. Requires accounting permissions. See the authentication page for cookie/JWT auth details and the pagination page for cursor semantics.

Optional parameters

  • Name
    cursor
    Type
    string
    Description

    Opaque pagination cursor returned by the previous response as nextCursor.

  • Name
    limit
    Type
    number
    Description

    Number of results to return. Accepts 1–200, defaults to 50.

Request

GET
/invoices
curl -G https://jarvis.bob-desk.com/invoices \
  -H "Cookie: session={cookie}" \
  -d limit=50

Response

{
  "items": [
    {
      "id": "64a1f3c89ab7e72a4fb4ae01",
      "client": "5d9b5b5b9ab7e72a4fb4ae69",
      "connection": "64a0e1b29ab7e72a4fb4ac10",
      "provider": "yooz",
      "externalId": "YZ-2024-00871",
      "supplier": {
        "externalId": "SUP-0042",
        "name": "Plomberie Dupont",
        "siret": "12345678900012",
        "siren": "123456789",
        "iban": "FR7612345987650123456789014"
      },
      "supplierId": "5d9b5b5b9ab7e72a4fb4ae99",
      "ticket": null,
      "number": "FA-2024-00871",
      "issueDate": "2024-06-01T00:00:00.000Z",
      "dueDate": "2024-07-01T00:00:00.000Z",
      "currency": "EUR",
      "amounts": {
        "ht": 1000.00,
        "tva": 200.00,
        "ttc": 1200.00
      },
      "vatBreakdown": [
        { "rate": 0.20, "base": 1000.00, "amount": 200.00 }
      ],
      "lines": [
        {
          "label": "Remplacement robinet",
          "qty": 1,
          "unitPrice": 1000.00,
          "ht": 1000.00,
          "vatRate": 0.20
        }
      ],
      "document": {
        "mime": "application/pdf",
        "ref": "https://storage.bob-desk.com/invoices/FA-2024-00871.pdf",
        "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      },
      "providerStatus": "validated",
      "matchHints": {
        "poRef": null,
        "ticketRef": "TK-20240588",
        "orderRef": null
      },
      "state": "ticket_unmatched",
      "createdAt": "2024-06-02T08:14:22.000Z",
      "updatedAt": "2024-06-02T08:14:22.000Z"
    }
  ],
  "nextCursor": "64a1f3c89ab7e72a4fb4ae02"
}

POST/invoices/:id/link

Projects the invoice as a facture line on the specified ticket view and transitions the invoice to the linked state. Requires accounting permissions. See the authentication page for cookie/JWT auth details.

The route :id and both body fields (ticketId, viewId) must be valid 24-character hex ObjectIds. Invalid input returns 422 Unprocessable Entity — see the errors page.

Route parameters

  • Name
    id
    Type
    string
    Description

    The invoice id to link.

Required body parameters

  • Name
    ticketId
    Type
    string
    Description

    Id of the ticket to link the invoice to.

  • Name
    viewId
    Type
    string
    Description

    Id of the ticket view (facture lot) on which the invoice line will be projected.

Request

POST
/invoices/:id/link
curl -X POST https://jarvis.bob-desk.com/invoices/64a1f3c89ab7e72a4fb4ae01/link \
  -H "Content-Type: application/json" \
  -H "Cookie: session={cookie}" \
  -d '{
    "ticketId": "63725f259ab7e72a4fb4ae69",
    "viewId": "63725f259ab7e72a4fb4ae70"
  }'

Response

{
  "ok": true
}

POST/invoices/:id/unlink

Removes the ticket association and returns the invoice to the ticket_unmatched state so it re-enters the manual-reconciliation queue. Requires accounting permissions. See the authentication page for cookie/JWT auth details.

The route :id must be a valid 24-character hex ObjectId; invalid input returns 422 Unprocessable Entity — see the errors page.

Route parameters

  • Name
    id
    Type
    string
    Description

    The invoice id to unlink.

Request

POST
/invoices/:id/unlink
curl -X POST https://jarvis.bob-desk.com/invoices/64a1f3c89ab7e72a4fb4ae01/unlink \
  -H "Content-Type: application/json" \
  -H "Cookie: session={cookie}"

Response

{
  "ok": true
}

POST/invoices/resync

Resync invoice

Re-enqueues an invoice for ingestion from the provider. Use this to force a re-fetch after a mapping fix or a transient provider error. Returns 202 Accepted on success. Returns 400 if the provider is unknown, 404 if there is no active connection for that provider. Requires accounting permissions. See the authentication page for cookie/JWT auth details.

Required body parameters

  • Name
    provider
    Type
    string
    Description

    The provider name, e.g. "yooz".

  • Name
    externalId
    Type
    string
    Description

    The provider-side invoice id to re-ingest.

Request

POST
/invoices/resync
curl -X POST https://jarvis.bob-desk.com/invoices/resync \
  -H "Content-Type: application/json" \
  -H "Cookie: session={cookie}" \
  -d '{
    "provider": "yooz",
    "externalId": "YZ-2024-00871"
  }'

Response

{
  "ok": true
}

POST/webhooks/invoice-providers/:provider

Provider webhook

Inbound webhook called by the AP provider when new invoice events are available. This endpoint is not called by API consumers — it is called by the provider itself.

Authentication uses an HMAC-SHA256 signature over the raw request body, passed in the x-yooz-signature header using the connection's configured webhook secret. Cookie/JWT auth is not used here.

Each event in the payload is enqueued for ingestion asynchronously.

Route parameters

  • Name
    provider
    Type
    string
    Description

    The provider identifier in the path, e.g. yooz.

Body parameters

  • Name
    clientId
    Type
    string
    Description

    Bob client/tenant id the events belong to.

  • Name
    events
    Type
    array
    Description

    Array of invoice event objects. Each entry contains:

    • invoiceId (provider-side invoice id to ingest)

Responses

  • Name
    202
    Type
    { accepted: number }
    Description

    Number of events successfully enqueued.

  • Name
    400
    Type
    error
    Description

    clientId is missing or refers to an unknown client.

  • Name
    401
    Type
    error
    Description

    HMAC signature is invalid or missing.

  • Name
    404
    Type
    error
    Description

    Unknown provider name or no active connection found for this client.

Request

POST
/webhooks/invoice-providers/:provider
curl -X POST https://jarvis.bob-desk.com/webhooks/invoice-providers/yooz \
  -H "Content-Type: application/json" \
  -H "x-yooz-signature: sha256=abc123def456..." \
  -d '{
    "clientId": "5d9b5b5b9ab7e72a4fb4ae69",
    "events": [
      { "invoiceId": "YZ-2024-00871" },
      { "invoiceId": "YZ-2024-00872" }
    ]
  }'

Response

{
  "accepted": 2
}