> 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 pulled public companies

GET https://api.spreadspace.app/api/loans/{loan_id}/public-companies

The public companies pulled onto the loan, by registrant name: each with its registrant summary, the forms and earliest year of its copied filings, when it was pulled, how many documents the copies make and each copied filing with its document ids. The companies ride the list envelope's `data`; the list is not paged (`has_more` is false and `next_cursor` null).

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

Reference: https://docs.spreadspace.app/api/api-reference/loans/list

## 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

- `loan_id` (string, required) — The loan's id.

### 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

- `data` (list of LoanPublicCompanyView, required)
- `has_more` (boolean, required)
- `next_cursor` (string, optional, nullable)

## 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

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

### 404 Not Found Error

Not Found

- `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

### LoanPublicCompanyView

A public company pulled onto a loan, with the documents its filings were copied into.

- `registrant` (PublicRegistrantSummary, required) — The company's registrant, with how many of its filings the store holds, its newest filing date and its logo.
- `forms` (list of string, required) — The forms of the copied filings, 10-K, then 10-Q, then 8-K, then S-1; an amendment counts as its base form.
- `from_year` (integer, required) — The earliest year among the copied documents: a document's fiscal year, else its period end's year, else its filing's filing year.
- `pulled_at` (datetime, required) — When the earliest of the copies was made.
- `document_count` (integer, required) — How many documents the copies make on the loan.
- `filings` (list of LoanPublicCompanyFiling, required) — The copied filings, by filing date, then accession.

### ApiErrorBody

Inner body of the canonical API error envelope.

- `type` (enum, required) — Stable error type identifier, one of the values listed. Pattern-match on this value, not the human-readable message. A later version may add a value; treat one you do not know by its HTTP status.
  - Allowed values: `billing_required`, `business_email_required`, `conflict`, `counterparty_not_in_plan`, `cursor_expired`, `custom_visual_limit_exceeded`, `doc_too_large`, `embed_not_in_plan`, `embed_origin_not_allowed`, `embed_scope_exceeds_key`, `embed_scope_not_allowed`, `embed_session_binding_mismatch`, `embed_session_not_found`, `embed_token_expired`, `forbidden`, `geometry_plan_denied`, `html_upload_disabled`, `idempotency_in_progress`, `idempotency_request_mismatch`, `idempotency_response_too_large`, `insufficient_credits`, `insufficient_scope`, `internal_error`, `invalid_code`, `invalid_cursor`, `invalid_embed_token`, `invalid_include`, `invalid_limit`, `invalid_request`, `invalid_session_handle`, `invalid_version`, `key_expired`, `key_revoked`, `last_item`, `license_assigned`, `license_holder_has_license`, `license_none_free`, `license_reassign_window`, `licenses_assigned`, `markets_api_required`, `memo_locked`, `memo_not_locked`, `mfa_enrollment_required`, `mode_mismatch`, `not_found`, `payload_too_large`, `payment_failed`, `pii_claim_required`, `rate_limited`, `render_failed`, `request_cancelled`, `research_not_in_plan`, `resource_gone`, `same_origin_required`, `sandbox_missing`, `sandbox_organization`, `scope_not_in_product`, `scope_state_changed`, `session_handle_already_used`, `session_handle_expired`, `session_handle_revoked`, `spend_cap_reached`, `spread_already_finalized`, `spread_limit`, `spread_locked`, `spread_not_finalized`, `spread_not_locked`, `spread_not_ready`, `spread_template_limit_exceeded`, `spreads_not_in_plan`, `spreadsheet_upload_disabled`, `statement_mapping_not_in_plan`, `subscription_required`, `surface_limit_exceeded`, `test_key_remint_required`, `unauthorized`, `unknown_factor`, `unprocessable`, `usage_throttled`, `validation_failed`
- `message` (string, required) — Human-readable error message. Subject to wording changes; do not parse.
- `code` (string, optional) — A finer, stable identifier within `type`, on the errors that carry one; absent otherwise. Pattern-match on it like `type`. The upload presign answers `not_found` with `loan_not_found` and `invalid_request` with `borrower_loan_mismatch`.
- `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.

### PublicRegistrantSummary

A registrant in the public filings store, with what the store holds for it.

- `cik` (string, required) — The registrant's SEC Central Index Key, ten digits with its leading zeros.
- `name` (string, required) — The registrant's name as filed.
- `tickers` (list of string, required) — The registrant's ticker symbols; empty when it has none.
- `exchanges` (list of string, required) — The exchanges the tickers trade on, in the tickers' order; empty when none.
- `filing_count` (integer, required) — How many of the registrant's filings the store holds, in any state.
- `sic` (string, optional, nullable) — The registrant's four-digit Standard Industrial Classification code, when known.
- `sic_description` (string, optional, nullable) — The classification's description, when known.
- `state` (string, optional, nullable) — The registrant's state of location, when known.
- `fiscal_year_end` (string, optional, nullable) — The fiscal year end as MMDD, when known.
- `latest_filing_date` (date, optional, nullable) — The filing date of the newest filing the store holds; null when none carries a date.
- `logo_url` (string, optional, nullable) — The address of the registrant's logo, a square WebP image: a stored copy when one is kept, else the logo provider's image for the registrant's first ticker; null when the registrant has neither.

### LoanPublicCompanyFiling

One public filing copied onto a loan.

- `accession` (string, required) — The filing's SEC accession number.
- `form` (string, required) — The form type as filed, such as 10-K, 10-Q/A or 8-K.
- `job_id` (string, required) — The id of the upload the filing's copies sit under on the loan.
- `document_ids` (list of string, required) — The ids of the documents copied from the filing, in the filing's order.
- `filing_date` (date, optional, nullable) — The date the filing was made, when known.
- `report_period` (date, optional, nullable) — The period end the filing reports on, when known.

## Examples

**Response**

```json
{
  "data": [
    {
      "registrant": {
        "cik": "0009900077",
        "name": "Larkspur Mills Inc",
        "tickers": [
          "LKSP"
        ],
        "exchanges": [
          "NYSE"
        ],
        "filing_count": 42,
        "sic": "2211",
        "sic_description": "Broadwoven Fabric Mills, Cotton",
        "state": "NC",
        "fiscal_year_end": "1231",
        "latest_filing_date": "2026-03-02",
        "logo_url": "https://assets.spreadspace.app/0009900077/9f2c1e7a4b8d3f60.webp"
      },
      "forms": [
        "10-K",
        "10-Q"
      ],
      "from_year": 2024,
      "pulled_at": "2026-03-05T16:40:08.512377+00:00",
      "document_count": 5,
      "filings": [
        {
          "accession": "0009900077-25-000041",
          "form": "10-Q",
          "job_id": "2f6e9a1c4b7d3e5f8a0c2b4e",
          "document_ids": [
            "6d0f8b2e4a5c7d9f1b3e5a7c",
            "7e1a9c3f5b6d8e0a2c4f6b8d"
          ],
          "filing_date": "2025-11-05",
          "report_period": "2025-09-30"
        },
        {
          "accession": "0009900077-26-000012",
          "form": "10-K",
          "job_id": "2f6e9a1c4b7d3e5f8a0c2b4d",
          "document_ids": [
            "3a7c5e9b1d2f4a6c8e0b3d5f",
            "4b8d6f0c2e3a5b7d9f1c4e6a",
            "5c9e7a1d3f4b6c8e0a2d4f6b"
          ],
          "filing_date": "2026-03-02",
          "report_period": "2025-12-31"
        }
      ]
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

**SDK Code**

```typescript
import { SpreadSpace } from '@spreadspace/sdk';

const client = new SpreadSpace({ apiKey: process.env.SPREADSPACE_API_KEY! });

const pulled = await client.loans.publicCompanies.list('9f8b7c6d5e4a3b2c1d0e4f5a');
for (const company of pulled.data) console.log(company.registrant.name, company.document_count);

```

```python
import os

from spreadspace import SpreadSpace

client = SpreadSpace(api_key=os.environ["SPREADSPACE_API_KEY"])

pulled = client.loans.public_companies.list("9f8b7c6d5e4a3b2c1d0e4f5a")
for company in pulled["data"]:
    print(company["registrant"]["name"], company["document_count"])

```

```csharp
using SpreadSpace;

using var client = new SpreadSpaceClient(Environment.GetEnvironmentVariable("SPREADSPACE_API_KEY"));

var pulled = await client.Loans.PublicCompanies.ListAsync("9f8b7c6d5e4a3b2c1d0e4f5a");
foreach (var company in pulled.Data) Console.WriteLine($"{company.Registrant.Name} {company.DocumentCount}");

```

```go
package main

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

func main() {

	url := "https://api.spreadspace.app/api/loans/9f8b7c6d5e4a3b2c1d0e4f5a/public-companies"

	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/loans/9f8b7c6d5e4a3b2c1d0e4f5a/public-companies")

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/loans/9f8b7c6d5e4a3b2c1d0e4f5a/public-companies")
  .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/loans/9f8b7c6d5e4a3b2c1d0e4f5a/public-companies', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```swift
import Foundation

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.spreadspace.app/api/loans/9f8b7c6d5e4a3b2c1d0e4f5a/public-companies")! 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()
```