---
title: "Tax transcript"
url: https://services.dev/docs/examples/tax/transcript
captured: [tax-build.txt, tax-flows.txt, tax-transcript-v3.txt]
---
# Tax transcript

URL: https://services.dev/docs/examples/tax/transcript

> Lender records, shaped like apis.tax's. A lender reads a return the brand filed, on the §7216 consent that names it, or orders a transcript on the taxpayer's Form 4506-C under the brand's own credential on a 120-day clock. Each field cites its form, year and line, and the acts that belong to people are refused.

*tax's words: return is a job, taxpayer is a subject, review is a task, preparer is a member (examples/tax/brand.ts).*

A lender needs a borrower's figures, each sourced, and the income figured the way underwriters figure it. When apis.tax prepared the return and the §7216 consent names the lender, the lender reads the filing itself, with no wait. Otherwise the taxpayer signs a Form 4506-C and the transcript is ordered under the brand's participant status.

```bash
cat services/transcript.ts
```

```txt title="captured/tax-build.txt · magic values: none"
import { Service } from 'services.dev'
import { selfEmployedIncome } from '../lib/tax.ts'
import rules from '../rules.ts'

// Lender records, on the taxpayer's consent, every field sourced. A lender orders a taxpayer's years from one of two
// sources. `filed`: the return apis.tax filed, read under the §7216 consent the taxpayer signed when it was prepared and
// that names this lender; each field cites that filing's receipt, form, year and line, with no wait and no new 4506-C.
// `ives`: the taxpayer signs a Form 4506-C, and the transcript is ordered under the brand's own participant status, on a
// clock that holds it to 120 days after the signature. Either way the AI reads the fields and the income is figured the
// Form 1084 way. It is published before it sells, answering not_live with its waitlist until the brand flips it live.
// Each year is charged on its own receipt, so a not-found is never charged.
export default Service({
  name: 'Tax Transcript',
  description: "Lender records on the taxpayer's consent, every field sourced.",
  status: 'roadmap',
  input: {
    taxpayer: 'party', ein: 'text?: the business, for a return apis.tax filed', tin_last4: 'text: such as 4417', years: 'number[]: such as 2024, 2025',
    source: ['filed', 'ives'], purpose: ['mortgage underwriting', 'business lending', 'quality control'],
  },
  output: { transcript: 'text: the transcript or the filing, by its receipt', fields: 'file', income: 'money', income_basis: 'file' },
  rules,
  deliver: {
    disclose: { act: 'disclose', when: job => job.input.source === 'filed', cite: "the taxpayer's §7216 consent, naming this lender" },
    consent: { ask: 'taxpayer', to: 'sign', what: 'Form 4506-C', how: 'esign', expires: '120d', when: job => job.input.source === 'ives' },
    order: { submit: 'https://transcripts.example.test/order', to: 'IRS, through the participant program', receipt: 'transcript', wait: '5d', when: job => job.input.source === 'ives' },
    fields: { by: 'ai', cite: 'the filing by its receipt, or the transcript: each field by its form, tax year and line' },
    income: { by: selfEmployedIncome, cite: 'Form 1084, 24-month average' },
  },
  clocks: { order: { due: '120d after consent', owner: 'brand', rungs: ['notice 30d', 'escalate 7d'], lapse: ['consent', 'cancel at $0'] } },
  price: { usd: 12, release: ['order', 'disclose'] },
})
```

| The lender gets | The step |
|---|---|
| A return the brand filed, on the consent that names the lender | `disclose`, held to the `disclose` row of the rules table, when `source` is `filed` |
| A transcript on the taxpayer's signed 4506-C | `consent`, the taxpayer's own e-signature, then `order` under the brand's `ives` credential, when `source` is `ives` |
| Received within 120 days of signing | the `order` clock, due `120d after consent`, owned by the brand |
| Each field with its form, year and line, and a filing's receipt | `fields`, AI, citing the filing or the transcript |
| Self-employed or business income, the Form 1084 way | `income`, your `selfEmployedIncome` in `lib/tax.ts` |
| No return prepared, no taxpayer represented, no consent signed for anyone | three refused rows in `rules.ts` |

Nothing is charged until the order's receipt or the disclosure, so a transcript not found costs nothing.

## Once it opens

On the taxpayer's 4506-C, the order runs against the participant program, and the income step figures the sample borrower's Schedule C:

```bash
node -e "import('./flows.ts')"   # the apis.tax door at 17a25d0: 16 flows in holdings/public/apis.tax/llms.txt and holdings/public/apis.tax/data.js
```

```txt title="magic values: none"
  llms.txt#income.analysis: Schedule C income added back the Fannie Mae Form 1084 way, by year, with the trend and the 24-month average when income is stable or rising
    → tax-example › figures the sample borrower's income the Form 1084 way · lib/tax.ts figures it, and the transcript's income step runs it on the fields it reads
  data.js#the sample borrower's income: 2024 $105,300 and 2025 $113,600 added back, increasing 7.88%, $9,120.83 a month on the 24-month average
    → tax-example › figures the sample borrower's income the Form 1084 way
```

## For lenders

Fern & Co's consent on its 2026 return names Harbor Bank for business lending, so Harbor Bank reads the filed return, each field cited to its receipt:

```txt
→ POST /returns {"service":"transcript","taxpayer":{"name":"Fern & Co","email":"books@fern.example"},"ein":"98-7654350","tin_last4":"4350","years":[2026],"source":"filed","purpose":"business lending","max_usd":12,"key":"tr-fern"}   # Harbor Bank's key
```

```txt title="captured/tax-transcript-v3.txt · magic values: none"
← job_4Tr1 · delivered · fields.json · income.json · $12.00 charged · at disclose: no wait, no 4506-C
  disclose  job_4Ta1's §7216 consent, ask_7Ha2, signed 2027-02-01 by Maya Fern as officer · names Harbor Bank, for business lending · until 2028-02-01 · rules 2026-10 · services['transcript'].disclose
  fields    Form 1120 · 2026 · line 28, taxable income · rcp_7Ha6 · line 31, total tax · rcp_7Ha6 · line 33, payments · rcp_7Ha6 and each payment's own receipt
            Form 100 · 2026 · line 18, net income · rcp_7Ha7
  income    the Form 1084 way, its Form 1120 section · one year filed, so the year alone, as the guide reads it
```

A lender the consent doesn't name is refused before any work, at $0, and `next` asks the taxpayer for a consent that names it:

```txt
→ POST /returns {"service":"transcript","taxpayer":{"name":"Fern & Co","email":"books@fern.example"},"ein":"98-7654350","tin_last4":"4350","years":[2026],"source":"filed","purpose":"business lending","max_usd":12,"key":"tr-fern-2"}   # Northline Credit's key
```

```txt title="magic values: none"
← 403 consent_required: disclose needs the taxpayer's §7216 consent to name this lender, and job_4Ta1's names Harbor Bank alone. Ask Maya Fern for one, or order with source: 'ives' and her Form 4506-C.
  cites  rules 2026-10 · services['transcript'].disclose
  next   hand_to_person https://apis.tax/asks/new?consent=7216&for=Northline%20Credit
```

## What it refuses

Three rows refuse the acts that belong to people, and route two of them to the brand's own Services. Every rules row is illustrative, and [the rules table](https://services.dev/docs/examples/tax/rules.md#a-refused-act) shows a refusal answered:

```bash
grep -A5 "transcript: {" rules.ts
```

```txt title="magic values: none"
    transcript: {
      order: { reserved: { brand: 'ives' }, position: 'Transcripts are ordered through the brand\'s participant status.' },
      disclose: filing.disclose,
      prepare_return: { refused: true, route: 'https://apis.tax/annual-return', position: 'A paid preparer with a PTIN prepares a return: the transcript door prepares none.' },
      represent_taxpayer: { refused: true, route: 'https://apis.tax/notice-response', position: 'A CPA, enrolled agent or attorney represents a taxpayer: the transcript door represents none.' },
      sign_consent: { refused: true, position: 'The taxpayer signs the consent: nothing here signs for them.' },
```

## Before it opens

The brand publishes the Service before it sells, at `status: 'roadmap'`, while its participant credential is verified: it's on the site with its price, in every surface's catalog, and an order answers `not_live`, holds nothing, and hands over the waitlist as `next`. Flip it to `'live'` and the same file takes orders:

```txt
→ POST /returns {"service":"transcript","taxpayer":{"name":"Avery Example","email":"avery@example.com"},"tin_last4":"4417","years":[2024,2025],"source":"ives","purpose":"mortgage underwriting","max_usd":12,"key":"tr-avery"}
```

```json title="captured/tax-transcript-v3.txt · 403 · magic values: none"
{
  "type": "BLOCKED",
  "category": "unavailable",
  "code": "not_live",
  "reason": "Tax Transcript is on the roadmap: published with its price, and taking no orders yet.",
  "next": {
    "do": "waitlist",
    "service": "transcript",
    "arguments": {
      "email": null
    },
    "tool": null,
    "http": "POST http://localhost:8787/transcript/waitlist",
    "url": "http://localhost:8787/transcript"
  },
  "doc_url": "https://apis.tax/docs/errors/not_live",
  "simulated": true
}
```

```txt
→ POST /transcript/waitlist {"email":"underwriting@lender.example"}
```

```txt title="magic values: none"
← 200 {"object":"waitlist","service":"transcript","status":"roadmap","position":1,"simulated":true}
```

[Publish before it takes orders](https://services.dev/docs/service/status.md) has every form of `status`.

---

- Up: [The tax example](https://services.dev/docs/examples/tax.md)
- Previous: [Information returns](https://services.dev/docs/examples/tax/information-returns.md)
- Next: [When a date is missed](https://services.dev/docs/examples/tax/missed.md)
