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

# List journal entries

> The journal entries in a period, in chronological order, a page at a time, each with its lines.
`from` and `to` are months (`yyyy-MM`) and both are included. A period spans at most 12 months; for a longer
history, ask one year at a time.

`series` is `SalesInvoice`, `CreditNote`, `SupplierInvoice`, `Bank` or `Manual`; `status` is `Posted` or
`Reversed`. A correcting entry names the posted entry it corrects in `correctsEntryId`.



## OpenAPI

````yaml /api-reference/openapi.json get /v1/journal-entries
openapi: 3.0.4
info:
  title: Envoi API
  description: >-
    The Envoi API lets your own systems work with an Envoi account: create and
    send invoices, record payments,

    keep the customer register in step, and read the books. An online store such
    as Nordvik Handel AS can, for example,

    create an invoice in Envoi for every B2B order from its web shop and mark it
    paid when the money arrives.


    **Base URL.** `https://api.envoi.no`. Every path starts with `/v1`.


    **Authentication.** An Owner or Admin creates an API client in Envoi under
    *Settings → API clients* (in the app: *Innstillinger → API-klienter*) and

    gets a Client ID and a client secret (shown once). Exchange them for an
    access token at `POST /v1/oauth/token`

    (OAuth 2.0 client credentials) and send it as `Authorization: Bearer
    {access_token}`. A token lives 15 minutes;

    ask for a new one when it expires. Every request is checked against Envoi's
    database, not only the token:

    deleting the client, rotating its secret or removing a scope takes effect on
    the next request.


    **Accounts and environments.** A token acts on one account, named by its
    Account ID in the token request's

    `audience`: `P11112001` is the production account, `T11112001` its test
    environment. Nothing done

    in the test environment reaches a real customer: emails are captured, not
    delivered. An id from another account, or

    from the other environment, is `404 not-found`, never `403`.


    **Scopes.** Each endpoint needs one scope, such as `invoices:read`. Levels
    nest: `admin` includes `write`,

    `write` includes `read`. A request without the scope is `403
    insufficient_scope`.


    **Errors.** Every error is JSON: `{ "code": "...", "message": "..." }`,
    sometimes with `details`, and with

    `errors` (one entry per field) on `400 validation-failed`. Branch on `code`;
    the message is for developers

    and may change. The token endpoint uses the OAuth shape `{ "error": "..." }`
    instead.


    **Idempotency.** Every POST needs an `Idempotency-Key` header. A retry with
    the same key and the same request

    gets the first answer again instead of creating a second invoice or payment.


    **Paging.** Lists take `page` (from 1) and `pageSize` (1 to 100) and answer

    `{ "items": [...], "page": 1, "pageSize": 20, "totalCount": 57, "hasMore":
    true }`.


    **Values.** JSON in camelCase. Dates are `yyyy-MM-dd`; timestamps ISO 8601
    in UTC. Money is in kroner as a

    decimal number; `currency` is always `NOK` in v1. VAT codes are the SAF-T
    standard codes (for sales:

    `3` = 25 %, `31` = 15 %, `33` = 12 %, `5` = exempt, `6` = outside the VAT
    Act, `7` = no VAT treatment, `52` = export).


    **Rate limits.** Each API client may send 600 requests a minute; the token
    endpoint allows 60 requests a minute

    per IP address and 30 per Client ID. Above that the answer is `429` with a
    `Retry-After` header.
  version: v1
servers:
  - url: https://api.envoi.no
    description: >-
      Production and test environment (the token's audience picks the
      environment)
security: []
tags:
  - name: Authentication
    description: >-
      Get an access token with the OAuth 2.0 client credentials grant, and see
      which API client and account a token belongs to.
  - name: Invoices
    description: >-
      Create draft invoices, send them, record payments, and read invoices. The
      same rules as in the Envoi app.
  - name: Clients
    description: The account's customer register.
  - name: Accounting
    description: >-
      Read-only views of the built-in books: the chart of accounts and journal
      entries. Only when Envoi's built-in accounting is turned on for the
      account.
paths:
  /v1/journal-entries:
    get:
      tags:
        - Accounting
      summary: List journal entries
      description: >-
        The journal entries in a period, in chronological order, a page at a
        time, each with its lines.

        `from` and `to` are months (`yyyy-MM`) and both are included. A period
        spans at most 12 months; for a longer

        history, ask one year at a time.


        `series` is `SalesInvoice`, `CreditNote`, `SupplierInvoice`, `Bank` or
        `Manual`; `status` is `Posted` or

        `Reversed`. A correcting entry names the posted entry it corrects in
        `correctsEntryId`.
      operationId: listJournalEntries
      parameters:
        - name: from
          in: query
          description: The first month, `yyyy-MM`. Required.
          required: true
          schema:
            type: string
          example: 2026-01
        - name: to
          in: query
          description: The last month, `yyyy-MM`. Required.
          required: true
          schema:
            type: string
          example: 2026-12
        - name: page
          in: query
          description: The page, from 1.
          schema:
            minimum: 1
            type: integer
            format: int32
            default: 1
          example: 1
        - name: pageSize
          in: query
          description: Entries per page, 1 to 100.
          schema:
            maximum: 100
            minimum: 1
            type: integer
            format: int32
            default: 50
          example: 50
      responses:
        '200':
          description: A page of journal entries.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JournalEntryPage'
              example:
                items:
                  - id: 5a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d
                    series: SalesInvoice
                    number: 12
                    documentDate: '2026-09-29'
                    postingDate: '2026-09-29'
                    description: Faktura 10023
                    status: Posted
                    sourceDocumentType: Invoice
                    sourceDocumentId: 8b6f2a4e-1c3d-4e5f-9a7b-2c4d6e8f0a12
                    correctsEntryId: null
                    lines:
                      - lineNumber: 1
                        account: '1500'
                        accountName: Kundefordringer
                        description: null
                        debit: 1250
                        credit: 0
                        vatCode: null
                        customerId: c2a9d4e1-5b7f-4c3a-8e6d-1f2a3b4c5d6e
                        supplierId: null
                        projectId: null
                      - lineNumber: 2
                        account: '3000'
                        accountName: Salgsinntekt handelsvarer, avgiftspliktig, høy sats
                        description: null
                        debit: 0
                        credit: 1000
                        vatCode: '3'
                        customerId: null
                        supplierId: null
                        projectId: null
                      - lineNumber: 3
                        account: '2700'
                        accountName: Utgående merverdiavgift, høy sats
                        description: null
                        debit: 0
                        credit: 250
                        vatCode: null
                        customerId: null
                        supplierId: null
                        projectId: null
                page: 1
                pageSize: 50
                totalCount: 1
                hasMore: false
        '400':
          description: >-
            - `validation-failed`: `from` or `to` missing or not `yyyy-MM`
            (`year-month-required`), `page` below 1 (`greater-than-or-equal`),
            or `pageSize` outside 1 to 100 (`out-of-range`).

            - `period-too-long`: the period spans more than 12 months;
            `details.maxMonths` is the limit.

            - `invalid-period`: `from` is after `to`, or a year is outside 2000
            to 2100.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                period-too-long:
                  summary: period-too-long
                  value:
                    code: period-too-long
                    message: The period may span at most 12 months.
                    details:
                      maxMonths: 12
        '401':
          description: >-
            - `unauthorized`: no token, an invalid or expired one, or a token
            the per-request check refuses (the client or its grant was deleted,
            the secret was rotated, or the account is being closed). Header
            `WWW-Authenticate: Bearer error="invalid_token"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                unauthorized:
                  summary: unauthorized
                  value:
                    code: unauthorized
                    message: A valid API client access token is required.
        '403':
          description: >-
            - `insufficient_scope`: the grant does not hold `bilag:read` (or a
            higher level of it).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                insufficient_scope:
                  summary: insufficient_scope
                  value:
                    code: insufficient_scope
                    message: This API client needs bilag:read.
        '409':
          description: >-
            - `accounting-not-enabled`: Envoi's built-in accounting is not
            turned on for this account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                accounting-not-enabled:
                  summary: accounting-not-enabled
                  value:
                    code: accounting-not-enabled
                    message: Accounting is not enabled for this account.
        '429':
          description: >-
            - `rate_limited`: this API client sent too many requests. Wait the
            number of seconds in `Retry-After`.
          headers:
            Retry-After:
              description: Seconds to wait before the next request.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                rate_limited:
                  summary: rate_limited
                  value:
                    code: rate_limited
                    message: Too many requests; try again later.
        '500':
          description: >-
            - `server-error`: something unexpected went wrong. The message never
            contains details. On a POST the `Idempotency-Key` is released, so
            retrying with the same key is safe.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                server-error:
                  summary: server-error
                  value:
                    code: server-error
                    message: >-
                      The request could not be completed. It is safe to retry
                      with the same Idempotency-Key.
      security:
        - oauth2:
            - bilag:read
        - bearerAuth: []
components:
  schemas:
    JournalEntryPage:
      required:
        - hasMore
        - items
        - page
        - pageSize
        - totalCount
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/JournalEntry'
          description: The items on this page.
        page:
          type: integer
          description: This page's number, from 1.
          format: int32
        pageSize:
          type: integer
          description: The page size asked for.
          format: int32
        totalCount:
          type: integer
          description: How many items there are on all pages together.
          format: int32
        hasMore:
          type: boolean
          description: True when there is a next page.
      description: One page of a list.
    Error:
      required:
        - code
        - message
      type: object
      properties:
        code:
          type: string
          description: >-
            A stable, machine-readable code, for example `not-found` or
            `insufficient_scope`. Branch on this, never on the message.
        message:
          type: string
          description: >-
            A short English sentence for a developer. Never contains customer
            data and may change.
        details:
          type: object
          additionalProperties: {}
          description: >-
            Extra facts for some codes, for example `existingId` on
            `client-exists`, `outstanding` on `payment-exceeds-outstanding`,
            `maxMonths` on `period-too-long`. Absent otherwise.
          nullable: true
        errors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
          description: >-
            Present only on `validation-failed`: one entry per field that
            failed.
          nullable: true
      description: The error body of every `/v1` endpoint except the token endpoint.
    JournalEntry:
      required:
        - description
        - documentDate
        - id
        - lines
        - number
        - postingDate
        - series
        - status
      type: object
      properties:
        id:
          type: string
          description: The entry's id.
          format: uuid
        series:
          type: string
          description: '`SalesInvoice`, `CreditNote`, `SupplierInvoice`, `Bank` or `Manual`.'
        number:
          type: integer
          description: The entry number within its series.
          format: int64
        documentDate:
          type: string
          description: The document's date.
          format: date
        postingDate:
          type: string
          description: The date it is posted on.
          format: date
        description:
          type: string
          description: The entry's text.
        status:
          type: string
          description: '`Posted` or `Reversed`.'
        sourceDocumentType:
          type: string
          description: What the entry was made from, for example `Invoice`, or null.
          nullable: true
        sourceDocumentId:
          type: string
          description: The id of that document, for example the invoice's id, or null.
          format: uuid
          nullable: true
        correctsEntryId:
          type: string
          description: The posted entry this one corrects, or null.
          format: uuid
          nullable: true
        lines:
          type: array
          items:
            $ref: '#/components/schemas/JournalLine'
          description: The entry's lines.
      description: A journal entry.
    FieldError:
      required:
        - code
        - field
      type: object
      properties:
        field:
          type: string
          description: >-
            The field's path in the request, for example `dueDate` or
            `lines[0].quantity`.
        code:
          type: string
          description: A stable kebab-case code, for example `required` or `greater-than`.
      description: A field that failed validation.
    JournalLine:
      required:
        - account
        - credit
        - debit
        - lineNumber
      type: object
      properties:
        lineNumber:
          type: integer
          description: The line's number within the entry.
          format: int32
        account:
          type: string
          description: The account number.
        accountName:
          type: string
          description: The account's name.
          nullable: true
        description:
          type: string
          description: The line's text, or null.
          nullable: true
        debit:
          type: number
          description: Debit amount in kroner.
        credit:
          type: number
          description: Credit amount in kroner.
        vatCode:
          type: string
          description: The line's VAT code, or null.
          nullable: true
        customerId:
          type: string
          description: The customer the line belongs to, or null.
          format: uuid
          nullable: true
        supplierId:
          type: string
          description: The supplier the line belongs to, or null.
          format: uuid
          nullable: true
        projectId:
          type: string
          description: The project the line belongs to, or null.
          format: uuid
          nullable: true
      description: A line of a journal entry.
  securitySchemes:
    oauth2:
      type: oauth2
      description: >-
        OAuth 2.0 client credentials. The token request also needs the
        `audience` form field (the Account ID), which OAuth tooling does not
        always send; see `POST /v1/oauth/token`.
      flows:
        clientCredentials:
          tokenUrl: https://api.envoi.no/v1/oauth/token
          scopes:
            bilag:read: >-
              Read access to the books (the chart of accounts and journal
              entries).
            bilag:write: >-
              Write access to the books (the chart of accounts and journal
              entries). Includes bilag:read.
            clients:admin: Admin access to clients. Includes clients:write and clients:read.
            clients:read: Read access to clients.
            clients:write: Write access to clients. Includes clients:read.
            invoices:admin: >-
              Admin access to invoices. Includes invoices:write and
              invoices:read.
            invoices:read: Read access to invoices.
            invoices:write: Write access to invoices. Includes invoices:read.
    bearerAuth:
      type: http
      description: >-
        The `access_token` from `POST /v1/oauth/token`, as `Authorization:
        Bearer {access_token}`. It lives 15 minutes.
      scheme: bearer
      bearerFormat: JWT

````