> This page is for API.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.spreadspace.app/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.spreadspace.app/_mcp/server.

# List all profit loss statements

GET https://api.spreadspace.app/api/borrowers/{borrower_id}/extractions/profit-loss-statements

Lists every usable profit loss statement on the borrower's file. Duplicates and failed extractions are left out, and you can pass `loan_id` to narrow the list to one loan.

Requires the `extractions:read` scope. Rate limit: 200 requests per minute per key (the `api` lane).

Reference: https://docs.spreadspace.app/api/api-reference/profit-loss-statements/get-profit-loss-statements

## Authentication

- `Authorization` header (bearer token, required) — Bearer token. Use `ss_live_…` for live data or `ss_test_…` for the sandbox (test mode). See [Authentication](https://docs.spreadspace.app/api/authentication).

## Request

### Path parameters

- `borrower_id` (string, required) — The borrower's id.

### Query parameters

- `loan_id` (string, optional) — Narrow the list to one loan.

### Headers

- `SpreadSpace-Version` (string, optional) — Pin the API version, e.g. `2026-10-07`. Omit to get the latest. See [Versioning](https://docs.spreadspace.app/api/versioning).

## Response

### 200

OK

- `borrower_id` (string, required) — The borrower the documents belong to.
- `statements` (list of ProfitLossStatementReportDataListItem, required) — One row per document.

## Errors

### 400 Bad Request Error

Bad request: validation failed, the cursor is malformed, or the API version is unknown.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 401 Unauthorized Error

Unauthorized: the bearer token or API key is missing or invalid.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 402 Payment Required Error

Payment required: the standard error envelope with `type` `subscription_required` when the workspace has no active or trialing subscription, or `billing_required` where a plan entitlement applies.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 403 Forbidden Error

Forbidden: authentication succeeded but the caller is not permitted to perform this action, for example an API key missing the required scope, an embed session reaching a loan it was not minted for, or a feature outside the workspace's plan.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 404 Not Found Error

Not found: the resource does not exist or is not visible to the calling tenant.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 429 Too Many Requests Error

Too many requests: the rate limit was hit, or an idempotency-key replay is still in progress.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

### 500 Internal Server Error

Internal server error: an unexpected failure. Quote the `request_id` in support tickets. A mutation sent with an `Idempotency-Key` replays this fault under that key rather than re-running; confirm the resource state before resending with a new key.

- `error` (ApiErrorBody, required) — Inner body of the canonical API error envelope.

## Types

### ProfitLossStatementReportDataListItem

One row of the Profit and Loss Statement list: the document's identity and its extracted object.

- `extracted_document_id` (string, required) — Identifier of the extracted document.
- `document_category` (string, required) — The document category the extraction is stored under.
- `report_data` (Profit and Loss Statement, required) — The extracted object, in the family's shape.

### ApiErrorBody

Inner body of the canonical API error envelope.

- `type` (string, required) — Stable error type identifier. Pattern-match on this value, not the human-readable message.
- `message` (string, required) — Human-readable error message. Subject to wording changes; do not parse.
- `request_id` (string, optional, nullable) — Per-request correlation ID (matches `X-Request-ID` response header). Quote in support tickets.
- `details` (map from string to string, optional, nullable) — Structured detail. Some error types populate documented keys in every environment: a version conflict (409) carries `current_version`, the version the resource is actually at, so the client can reload and re-apply. Free-form diagnostic detail beyond those keys appears in development environments only. An `insufficient_credits` 402 carries `balance_usd`, `reserved_usd`, `in_flight_docs`, `incoming_docs` and `per_doc_reservation_usd` as decimal strings.

### Profit and Loss Statement

A profit and loss statement: the printed lines with their figures per period column. Figures are decimal strings with two decimals, in dollars.

- `entity` (string, required, nullable) — The reporting entity's name as printed.
- `title` (string, required, nullable) — The statement's printed title.
- `period` (string, required, nullable) — The reporting period as printed in the heading.
- `period_source` (string, required, nullable) — Which part of the document states the reporting period: the printed heading (`printed`), the date the statement was printed on (`print_stamp`), a year the heading prints alone (`year_only`, the period being that year's end), the page image (`page_image`), the file's name (`filename`) or the file's own creation date (`file_metadata`); null when none of these dates the statement.
- `periods` (list of ProfitLossStatementReportData_ProfitLossPeriod, required) — The statement's figure columns, one entry per column.
- `billing_years` (integer, required) — Years of data billed: the distinct years among columns that print a non-zero figure; 0 when no column prints one (such a document is not billed).
- `columns` (integer, required) — Number of figure columns.
- `lines` (list of ProfitLossStatementReportData_ProfitLossLine, required) — The printed lines in order.
- `entity_source` (string, optional) — What names the entity when the statement's own page does not: the page image (`page_image`), the filing's cover page (`filing_cover`), or the opening pages of the financial statement packet the statement arrived in (`packet_text`); absent when the statement's own page names it.
- `entity_source_sheet` (string, optional) — The sheet of the uploaded workbook that names the company, when this statement's own sheet does not and the workbook names exactly one company; absent otherwise.
- `reporting_unit` (enum, optional) — The unit the figures are printed in; on the wire the figures are already whole dollars.
  - Allowed values: `ones`, `thousands`, `millions`, `billions`
- `scale_multiplier` (integer, optional) — Scale of the printed figures: 1 for whole dollars, 1000 when the statement is stated in thousands, 1000000 when it is stated in millions, 1000000000 when it is stated in billions.
- `unit_exceptions` (list of string, optional) — The carve-outs the statement's unit declaration lists, such as per share amounts, whose lines and columns keep their printed figures; empty when it lists none.
- `unit_source` (enum, optional) — Where the statement states its unit: `printed` when the statement header, a column header or a heading line prints it; `none` when nothing is printed and the figures are whole dollars as printed.
  - Allowed values: `printed`, `none`
- `component_columns` (list of ProfitLossStatementReportData_ProfitLossComponentColumn, optional) — The columns the statement prints beside a total as its parts, such as one per class or location, when it prints any.
- `entity_split` (ProfitLossStatementReportData_ProfitLossEntitySplit, optional) — Which part of a page whose columns are separate companies this statement is; absent on every other statement.
- `canonical` (ProfitLossStatementReportData_CanonicalAnnotation, optional) — The printed lines mapped onto standard line names.
- `per_share` (ProfitLossStatementReportData_ProfitLossPerShare, optional) — The per-share block printed under the bottom line, when the statement prints one: earnings per share and weighted-average shares, basic and diluted, one row each as printed.
- `supplemental` (ProfitLossStatementReportData_ProfitLossSupplemental, optional) — The rows printed under the bottom line besides the per-share block, when the statement prints any: other comprehensive income, a retained earnings roll-forward, supplemental lines.
- `cpa_engagement` (integer, optional) — The accountant's level of assurance: 0 unaudited, 1 compiled, 2 reviewed, 3 audited.
- `cpa_engagement_label` (string, optional) — The assurance level in words.
- `presentation` (enum, optional) — How the statement is presented: `formal` when it is presented as issued financial statements (a CPA engagement stated, a reference to the notes to the financial statements, a per-share block, the supplemental cash flow disclosures, the preparation legend that no assurance is provided, a plural statement title such as balance sheets or statements of income, or a statement of changes in equity or plural statement titles in the packet it arrived in); `free_form` when it is a report out of the books (accounting software or a spreadsheet).
  - Allowed values: `formal`, `free_form`
- `signals` (list of ProfitLossStatementReportData_StatementSignal, optional) — Notes about the statement's reporting period, when any.
- `packet` (ProfitLossStatementReportData_PacketProvenance, optional) — Where the statement sat in the financial statement packet it arrived in, when it arrived in one.
- `summary` (ProfitLossStatementReportData_StatementSummary, optional) — The statement's headline figures, on the single-document read.

### ProfitLossStatementReportData_ProfitLossPeriod

One figure column.

- `label` (string, required, nullable) — The column header as printed.
- `coverage` (string, required, nullable) — The span of time the column covers.
- `start` (string, optional, nullable) — First day of the period, when the header states one.
- `end` (string, optional, nullable) — Last day of the period, when the header states one.
- `rollup` (boolean, optional) — True when the column totals the other columns.
- `consolidating_columns` (integer, optional) — On a consolidating statement, the number of entity columns the total spans.

### ProfitLossStatementReportData_ProfitLossLine

One printed line.

- `label` (string, required) — The line's label as printed.
- `depth` (integer, required) — Indentation level of the line, counting from zero.
- `values` (list of string, required) — The line's figure per column; null where the column is blank.
- `component_values` (list of string, optional) — The line's figure in each component column, in the order of component_columns; null where the column is blank.

### ProfitLossStatementReportData_ProfitLossComponentColumn

One column printed as a part of a total column.

- `label` (string, required, nullable) — The column header as printed; null when the column prints none.
- `total_column` (integer, required) — Position among the statement's period columns of the total the component is a part of, counting from zero.
- `after_total` (boolean, optional) — True when the column is printed to the right of its total; absent otherwise.

### ProfitLossStatementReportData_ProfitLossEntitySplit

The statement's place on a page whose columns are separate companies.

- `role` (enum, required) — `total` on the statement of the page's total column, `member` on the statement of one company's column.
  - Allowed values: `total`, `member`
- `members` (list of string, optional) — On the total's statement, the names of the companies whose columns the page prints.
- `total` (string, optional, nullable) — On a member's statement, the entity the page's total column is for, or null when the page prints no total.

### ProfitLossStatementReportData_CanonicalAnnotation

The statement's printed lines mapped onto standard line names, with the footing of each printed subtotal.

- `schema_version` (string, required, nullable) — Version of the standard line vocabulary the names come from.
- `statement` (string, required) — Which statement vocabulary applies: balance_sheet, income_statement or cash_flow.
- `rows` (list of ProfitLossStatementReportData_CanonicalRow, required) — One entry per printed line, in print order.
- `blocks` (list of ProfitLossStatementReportData_CanonicalBlock, required) — One entry per printed subtotal and the lines that foot into it.
- `gates` (ProfitLossStatementReportData_CanonicalGates, required) — Summary verdicts over the whole statement.
- `entity_signal` (string, required, nullable) — A note about the entity the statement belongs to, when the line names carry one.

### ProfitLossStatementReportData_ProfitLossPerShare

The per-share block under the bottom line.

- `rows` (list of ProfitLossStatementReportData_ProfitLossPerShareRow, required) — One row per printed per-share or share-count line, in print order.
- `share_unit` (string, required) — The unit the share counts were printed in (ones, thousands, millions); the values are already whole shares.

### ProfitLossStatementReportData_ProfitLossSupplemental

The rows printed under the bottom line besides the per-share block.

- `rows` (list of ProfitLossStatementReportData_ProfitLossSupplementalRow, required) — One row per printed line, in print order.

### ProfitLossStatementReportData_StatementSignal

A note about the statement's reporting period.

- `severity` (enum, required) — How much weight the note carries: info or warn.
  - Allowed values: `info`, `warn`
- `code` (enum, required) — The note's identifier.
  - Allowed values: `coverage_unreadable`, `interest_netted_with_other`, `line_enters_against_its_name`, `no_reporting_period`, `year_from_file_metadata`, `year_from_filename`, `year_from_page_image`, `year_matches_print_stamp`
- `detail` (string, required) — The note in words.

### ProfitLossStatementReportData_PacketProvenance

Where a statement sat in the financial statement packet it arrived in, when it arrived in one.

- `section_index` (integer, required) — Position of the statement among the packet's statements, counting from zero.
- `pages` (list of integer, required) — First and last page of the statement within the packet, counting from one.
- `letter_date` (string, required, nullable) — Date of the accountant's letter that accompanied the packet, when the letter printed one.
- `letter_page` (integer, required, nullable) — Page of the packet the accountant's letter is on, when the packet carries one.
- `page_list` (list of integer, optional) — Every page of the packet the statement is printed on, counting from one, when they are not one unbroken run; absent otherwise.

### ProfitLossStatementReportData_StatementSummary

The statement's headline figures: one block of rows per section, titled by the period the rows cover.

- `title` (string, required) — The period the rows cover, as a heading.
- `sections` (list of ProfitLossStatementReportData_StatementSummarySection, required) — The row blocks, in display order.

### ProfitLossStatementReportData_CanonicalRow

One printed line and the standard line name it corresponds to.

- `key` (string, required) — Address of the printed line within the statement.
- `raw_label` (string, required, nullable) — The line's label as printed.
- `concept_id` (string, required, nullable) — The standard line name the printed label corresponds to, or null when it corresponds to none.
- `method` (enum, required) — How closely the printed label matches the standard name: exact, fuzzy, structural, or reconciled when it matches none.
  - Allowed values: `exact`, `fuzzy`, `keyword`, `structural`, `reconciled`
- `block` (string, required, nullable) — The subtotal block the line belongs to, when it belongs to one.
- `parent_concept_id` (string, required, nullable) — The standard name of the subtotal the line foots into, when it foots into one.

### ProfitLossStatementReportData_CanonicalBlock

A printed subtotal and whether its lines foot into it.

- `id` (string, required) — Address of the subtotal's printed line.
- `parent_concept_id` (string, required, nullable) — The standard name of the subtotal, when it corresponds to one.
- `footing` (string, required) — Whether the lines above the subtotal add up to it: pass, fail or not_applicable.

### ProfitLossStatementReportData_CanonicalGates

Verdicts over the whole statement.

- `identity` (string, required) — Whether total assets equal total liabilities plus equity on every column: pass, fail or not_applicable.
- `classified_footing` (string, required) — Whether the current and noncurrent subtotals foot: pass, fail or not_applicable.
- `blocks_failed` (integer, required) — Number of printed subtotals whose lines do not add up to them.

### ProfitLossStatementReportData_ProfitLossPerShareRow

One per-share line as printed.

- `kind` (enum, required) — `eps` for a per-share figure (dollars per share to the cent, as printed), `shares` for a share count (whole shares).
  - Allowed values: `eps`, `shares`
- `basis` (enum, required) — `basic`, `diluted`, `basic_and_diluted`, or empty when the line states neither.
  - Allowed values: `basic`, `diluted`, `basic_and_diluted`, ``
- `label` (string, required) — The line's printed caption.
- `values` (list of string, required) — One value per figure column, as strings; null where the column prints none.

### ProfitLossStatementReportData_ProfitLossSupplementalRow

One line printed under the bottom line.

- `kind` (enum, required) — What the line belongs to: `oci` for other comprehensive income, `retained_earnings` for a retained earnings or equity roll-forward, `supplemental_info` for a supplemental disclosure, `other` for any other line.
  - Allowed values: `oci`, `retained_earnings`, `supplemental_info`, `other`
- `label` (string, required) — The line's printed caption.
- `is_header` (boolean, required) — True when the line heads the lines under it.
- `values` (list of string, required) — The line's figure per column; null where the column is blank.

### ProfitLossStatementReportData_StatementSummarySection

A block of headline rows under one heading.

- `key` (string, required) — The block's identifier, for example assets, liabilities or pl.
- `heading` (string, required, nullable) — The block's heading, or null when the block has none.
- `rows` (list of ProfitLossStatementReportData_StatementSummaryRow, required) — The rows of the block, in display order.

### ProfitLossStatementReportData_StatementSummaryRow

One headline figure and the printed line it names.

- `key` (string, required) — The row's identifier, for example revenue, cogs or net_profit.
- `label` (string, required) — The row's wording as displayed.
- `value` (string, required, nullable) — The figure in dollars, or null when the printed line carries no figure.
- `aggregated` (boolean, optional) — True when the figure combines more than one printed line rather than reading a single printed cell.
- `emphasis` (boolean, optional) — True on a section total or a bottom line.
- `depth` (integer, optional) — Indentation of the row beneath the row above it, counting from zero.
- `pinned` (boolean, optional) — True on a row that stays in view when its section is collapsed.

## Examples

**Response**

```json
{
  "borrower_id": "3f9c2b1e8d7a4c5b9e0f1a2b",
  "statements": [
    {
      "extracted_document_id": "7a1d4e9c2b3f4a5d8e6c1b0f",
      "document_category": "profit_and_loss",
      "report_data": {
        "entity": "Pinnacle Manufacturing LLC",
        "title": "Profit and Loss Statement",
        "period": "For the Year Ended December 31, 2024",
        "period_source": null,
        "periods": [
          {
            "label": "For the Year Ended December 31, 2024",
            "coverage": "For the Year Ended December 31, 2024"
          }
        ],
        "billing_years": 1,
        "columns": 1,
        "lines": [
          {
            "label": "REVENUE",
            "depth": 0,
            "values": [
              null
            ]
          },
          {
            "label": "Product Revenue",
            "depth": 1,
            "values": [
              "1657352.45"
            ]
          },
          {
            "label": "Service Revenue",
            "depth": 1,
            "values": [
              "697662.95"
            ]
          },
          {
            "label": "Total Revenue",
            "depth": 1,
            "values": [
              "2355015.40"
            ]
          },
          {
            "label": "COST OF GOODS SOLD",
            "depth": 0,
            "values": [
              null
            ]
          },
          {
            "label": "Materials",
            "depth": 1,
            "values": [
              "544202.39"
            ]
          },
          {
            "label": "Direct Labor",
            "depth": 1,
            "values": [
              "197195.78"
            ]
          },
          {
            "label": "Manufacturing Overhead",
            "depth": 1,
            "values": [
              "96048.44"
            ]
          },
          {
            "label": "Total COGS",
            "depth": 1,
            "values": [
              "837446.61"
            ]
          },
          {
            "label": "GROSS PROFIT",
            "depth": 0,
            "values": [
              "1517568.79"
            ]
          },
          {
            "label": "OPERATING EXPENSES",
            "depth": 0,
            "values": [
              null
            ]
          },
          {
            "label": "Salaries and Wages",
            "depth": 1,
            "values": [
              "290836.02"
            ]
          },
          {
            "label": "Rent Expense",
            "depth": 1,
            "values": [
              "45745.93"
            ]
          },
          {
            "label": "Utilities",
            "depth": 1,
            "values": [
              "6212.66"
            ]
          },
          {
            "label": "Insurance",
            "depth": 1,
            "values": [
              "15227.27"
            ]
          },
          {
            "label": "Marketing and Advertising",
            "depth": 1,
            "values": [
              "71176.85"
            ]
          },
          {
            "label": "Depreciation",
            "depth": 1,
            "values": [
              "36904.38"
            ]
          },
          {
            "label": "Office Supplies",
            "depth": 1,
            "values": [
              "5628.98"
            ]
          },
          {
            "label": "Professional Fees",
            "depth": 1,
            "values": [
              "24651.53"
            ]
          },
          {
            "label": "Total Operating Expenses",
            "depth": 1,
            "values": [
              "496383.62"
            ]
          },
          {
            "label": "OPERATING INCOME",
            "depth": 0,
            "values": [
              "1021185.17"
            ]
          },
          {
            "label": "OTHER INCOME / (EXPENSE)",
            "depth": 0,
            "values": [
              null
            ]
          },
          {
            "label": "Interest Expense",
            "depth": 1,
            "values": [
              "-24791.92"
            ]
          },
          {
            "label": "Other Income",
            "depth": 1,
            "values": [
              "8263.96"
            ]
          },
          {
            "label": "INCOME BEFORE TAX",
            "depth": 0,
            "values": [
              "1004657.21"
            ]
          },
          {
            "label": "Income Tax Expense (21%)",
            "depth": 0,
            "values": [
              "-210978.01"
            ]
          },
          {
            "label": "NET INCOME",
            "depth": 0,
            "values": [
              "793679.20"
            ]
          }
        ],
        "document_type": "profit_loss_statement"
      }
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.spreadspace.app/api/borrowers/3f9c2b1e8d7a4c5b9e0f1a2b/extractions/profit-loss-statements")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```