ModernTaxDevelopers Get sandbox keys
API

Transcripts as an endpoint, not a vendor portal.

One POST creates a verification. A webhook returns it — parsed JSON, the raw IRS HTML, and a PDF, in whatever shape your LOS actually wants. Built for platforms that own their own origination stack.

portal.moderntax.io/api
# Create a transcript request
curl -X POST https://portal.moderntax.io/api/intake/transcript \
  -H "x-api-key: mt_live_txn_yourco_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "request_token": "SBA-7a-4482",  // your id — also the idempotency key
    "entities": [{
      "entity_name": "Atlas Roofing LLC",
      "tid": "88-1213417",
      "tid_kind": "EIN",
      "form_type": "1120S",
      "years": ["2022", "2023", "2024"]
    }]
  }'

# 201 Created
{
  "request_id": "uuid",
  "request_token": "SBA-7a-4482",
  "status": "irs_queue",
  "entities": [{ "entity_id": "uuid", "status": "irs_queue" }],
  "usage": { "used": 47, "remaining": 953 }
}
# POST to your endpoint when the pull completes
# X-ModernTax-Signature: HMAC-SHA256 hex of the raw body
{
  "request_token": "SBA-7a-4482",
  "status": "complete",         // partial | complete | error
  "record_id": "uuid",           // deterministic — dedupe on this
  "record_type": "financial_verification",
  "generated_at": "2026-08-11T10:32:11Z",
  "entity": {
    "entity_name": "Atlas Roofing LLC",
    "tid": "88-1213417",
    "form_type": "1120S"
  },
  "data": { /* shape per record_type — see moderntax.io/docs */ }
}
Walkthrough

Two minutes, end to end.

The whole integration — creating an order, results by poll or webhook, the structured and cross-reference endpoints, and every error code you can hit.

Prefer to read it? The full API reference covers every field. Ordering rather than integrating? See the portal walkthrough.

Lifecycle

Four steps. That's the whole API.

A signed webhook fires when the pull completes, and GET /api/intake/transcript?token= is there if you'd rather poll.

01

Create

POST /api/intake/transcript with your entities, TINs, and years. Your request_token is the idempotency key — a retry returns 409, never a double order.

02

Authorize

Collect the 8821 signature in your own flow (Persona, DocuSign, wet-sign) and send it back — inline as signed_8821 on the create call or via POST /api/intake/8821-pdf, with signature evidence attached. Or let ModernTax collect it.

03

Pull

Status moves through irs_queue and processing. A credentialed expert on our network works the IRS PPS line with their own CAF — never a single shared credential.

04

Deliver

A webhook signed with X-ModernTax-Signature delivers parsed JSON, raw IRS HTML, and PDF. Same-day target available on integrated plans, 24h standard.

Response shape

You pick the schema. We conform to it.

Three named shapes — minimal, underwriting, raw. Pass schema= on the results call (GET /api/intake/transcript?token=…&schema=underwriting), or pin an org-wide default in the developer portal at portal.moderntax.io/developer. No parameter and no pin? The legacy response shape, unchanged — nothing breaks when we ship.

Same pull, three shapes

Per-entity payload for each schema= value. Every shape shares one envelope; PDF/HTML URLs are 1-hour signed.

// GET /api/intake/transcript?token=SBA-7a-4482&schema=minimal
// — just tell me if it's clean
{
  "id": "uuid",
  "name": "Atlas Roofing LLC",
  "form": "1120S",
  "years": ["2022", "2023", "2024"],
  "status": "completed",
  "years_filed": ["2022", "2023", "2024"],
  "years_unfiled": [],
  "flags": [],                          // [{type, severity, message}]
  "pdf": ["https://…"],                // 1-hour signed URLs
  "html": ["https://…"]
}
// schema: "underwriting" — everything in minimal, plus the lines a credit memo needs
{
  …all minimal fields…,
  "financials": [
    { "year": "2024", "form": "1120S",
      "gross_receipts": 4182910, "total_income": 4204118,
      "total_deductions": 3591630, "total_tax": 0,
      "account_balance": 0, "accrued_interest": 0,
      "accrued_penalty": 0, "account_balance_plus_accruals": 0 }
  ],
  "tax_liabilities": {
    "total_assessed": 0, "total_paid": 0,
    "total_balance": 0, "total_accrued": 0
  },
  "repayment_plan": {
    "has_installment_agreement": false,
    "has_offer_in_compromise": false,
    "has_currently_not_collectible": false,
    "details": null,
    "recommendation": "No balance due and no collection activity — clear to proceed."
  },
  "overall_severity": "CLEAN",      // CRITICAL | WARNING | CLEAN
  "headline": "Filed all 3 requested years. No balance due."
}
// schema: "raw" — you parse it yourself
{
  "id": "uuid",
  "name": "Atlas Roofing LLC",
  "form": "1120S",
  "years": ["2022", "2023", "2024"],
  "status": "completed",
  "retrieved_at": "2026-08-10T15:42:11Z",
  "artifacts": [
    { "kind": "pdf",  "file": "2024-record-of-account.pdf",
      "url": "https://…", "sha256": "9f2c…a41b" },
    { "kind": "html", "file": "2024-record-of-account.html",
      "url": "https://…", "sha256": "3d81…7c02" },
    { "kind": "signed_8821", "file": "signed-8821.pdf",
      "url": "https://…", "sha256": "77aa…09c3" }
  ]  // sha256 computed at serve time; null for legacy externally-stored artifacts
}
One record, two doors

API orders show up in the portal too.

An underwriter who logs in sees the request your LOS created — same record, same artifacts, same audit trail. Your engineers integrate; your credit team never has to.

What your LOS sees

Structured records delivered by webhook — HMAC-signed, with automatic retry and backoff. Configure the URL and secret self-serve in the developer portal.

# your handler
POST /webhooks/moderntax
X-ModernTax-Signature: 8a3f…  # HMAC-SHA256 hex of raw body

{ "request_token": "SBA-7a-4482",
  "status": "complete",
  "record_id": "uuid",
  "record_type": "financial_verification" }

What your underwriter sees

The identical request in the portal — including the ones nobody ordered by hand. Downloadable indefinitely, for the audit that shows up eight months later.

Loan SBA-7a-4482 · 3 entities
apiAtlas Roofing LLC · 1120SComplete
apiSierra Equipment · 1065Complete
portalR. Whitfield · 1040In progress
Record of Account · 3 yrs eachPDF · HTML · JSON

A network of CAFs, not one

Every pull runs under a credentialed practitioner's own CAF number and their own fax line. No single credential to get flagged — the failure mode that took the last API-first vendor offline doesn't exist here.

SBA SOP transcript quality

Records of Account and Return Transcripts delivered in the form the SOP expects, with source and retrieval timestamp on every artifact. Audit-defensible, not screenshots.

Monitoring that shuts itself off

Enroll a conditioned entity via POST /api/intake/monitoring and we re-poll until it lands, then auto-cancel. Billed only when a fresh pull returns something new — never for an empty check.

Broker & counterparty checks

A lightweight lien-and-compliance check on a 1099 individual or single-member entity — for vetting brokers, not underwriting a loan. Priced below a full verification.

Self-serve sandbox

Work email + company at portal.moderntax.io/sandbox gets you an instant {company}-sandbox key against synthetic data. Production-identical endpoints, 250 requests free — test before you talk to anyone.

Idempotent by contract

Your request_token is the idempotency key — a retried create returns 409, never a double charge or a double pull. Usage against your quota is visible in the developer portal.

Reference

Endpoints, in one place.

All requests authenticate with an x-api-key header against https://portal.moderntax.io. Keys, webhooks, default schema, and usage are managed self-serve at portal.moderntax.io/developer.

MethodEndpointWhat it does
POST /api/webhook/employment-intakeLive in production Submit an employment & income verification. Takes request_token, employee_name, employee_ssn, and years[]. Returns request_id plus a usage object with requests used and remaining.

Transcript verification endpoints

The transcript ordering, authorization-upload, and usage endpoints are documented in the full API reference at moderntax.io/docs. They are not reproduced here so this page can’t drift out of sync with the canonical reference — check the docs, or email matt@moderntax.io and we’ll send the current spec with your sandbox keys.

Pricing

From $39.99 per verified entity.

One flat per-entity price covers the Return Transcript, the Record of Account, entity-transcript detection, and compliance screening — there's no line-item ladder per document type. Where you land depends on committed monthly volume, and we'll quote it on a short call.

What you get at every price pointUnit rate
Per verified entity (TIN) Return Transcript + Record of Account, all requested years · entity-transcript / election-status detection included · compliance flag screening · unlimited team seats · REST API, webhooks and portal access on integrated plans. Rejections are never billed. Nothing re-pulls without you asking. Volume commitments move the rate down from here. from $39.99/ entity

What counts as billable

A definitive IRS result bills — including "no record of return filed," which is a real underwriting finding. Rejections (bad EIN, name mismatch, signer not on record) and abandoned pulls never bill, and we return the specific field to fix.

How we quote

Tell us your expected monthly entity volume and whether you're pulling for your own book or reselling under your own brand. We come back with a firm per-entity rate the same day — no procurement cycle to get a number. Quotes already in flight are honored exactly as written.

Get started

Sandbox keys in one reply.

Tell us your schema preference and volume band and we'll provision sandbox keys plus a staging webhook the same day — no procurement cycle to start testing.

Request sandbox keys Get a quote