ModernTax Partner API

Programmatic IRS transcript verification: submit an entity, obtain Form 8821 authorization, and receive the pulled transcripts plus a structured compliance read — by polling or by webhook.

Overview

A typical automated integration (how a reseller like a lending platform runs it end to end):

  1. Submit one or more entities to POST /api/intake/transcript.
  2. Authorize each entity with a signed IRS Form 8821 — either upload a pre-signed PDF you collected yourself (/api/intake/8821-pdf), or let ModernTax collect the signature (/api/intake/8821). See Authorization.
  3. Receive results — poll GET /api/intake/transcript?token=, or have ModernTax POST them to your webhook.

Every endpoint below is authenticated with an x-api-key header. The portal also exposes cookie-authenticated admin/expert/processor endpoints; those are internal and not part of this contract.

Authentication

All requests require an x-api-key header issued by ModernTax. Contact matt@moderntax.io to provision a key; new accounts include free test requests.

x-api-key: <your_api_key>
Content-Type: application/json    # or multipart/form-data where noted

Keys are stored as SHA-256 hashes and constant-time verified on every request. A missing or invalid key returns 401 via the same code path, so errors never reveal whether a partial match exists.

Base URL

https://portal.moderntax.io

Submit a transcript request

POST /api/intake/transcript

Creates a request with one or more entities and queues them for IRS retrieval.

This endpoint does not collect authorization. It records the entities and moves them to the IRS queue; you must supply a signed 8821 for each entity via one of the authorization endpoints before results can be delivered. Signer fields are not read here — set them on /api/intake/8821 if you want ModernTax to collect the signature.

Request

{
  "request_token": "your-loan-12345",   // unique per account; idempotency key
  "loan_number":   "your-loan-12345",   // optional; used in invoice itemization
  "entities": [
    {
      "entity_name": "ACME Holdings LLC",
      "tid":         "12-3456789",
      "tid_kind":    "EIN",              // "EIN" or "SSN"
      "form_type":   "1120S",            // optional; inferred from tid_kind if omitted
      "years":       ["2022","2023","2024"],
      "address": "123 Main St", "city": "Austin", "state": "TX", "zip_code": "78701",
      "loan_officer_name":  "Jane Rep",  // optional
      "loan_officer_email": "jane@lender.com",
      "fiscal_year_end_month": 12        // optional
    }
  ]
}
FieldReqNotes
request_tokenyesYour unique id for the request. Reusing one returns 409.
loan_numbernoFalls back to request_token. Used on invoices.
entities[].entity_nameyesLegal name on file with the IRS.
entities[].tid / tid_kindyesEIN (XX-XXXXXXX) or SSN (XXX-XX-XXXX); "EIN"/"SSN".
entities[].yearsyes4-digit years, 1990–2028.
entities[].form_typeno1120, 1120S, 1065, 1040, … Inferred from tid_kind if omitted.

Response 201

{
  "success": true,
  "request_id": "uuid",
  "request_token": "your-loan-12345",
  "loan_number": "your-loan-12345",
  "status": "irs_queue",
  "entities": [
    { "entity_id": "uuid", "entity_name": "ACME Holdings LLC",
      "form_type": "1120S", "years": ["2022","2023","2024"], "status": "irs_queue" }
  ],
  "usage": { "used": 47, "remaining": 953, "limit": 1000 }
}

Errors: 401 (auth), 402 (account not enrolled in billing — see Pricing), 409 (duplicate request_token).

Authorization — IRS Form 8821

The IRS requires a signed Form 8821 authorizing ModernTax as designee before transcripts can be pulled. Two integration models:

A. Upload a pre-signed 8821 (you collect the signature)

POST /api/intake/8821-pdf

For partners who obtain the borrower's signature through their own workflow (DocuSign, wet-sign, etc.). The entity advances straight to 8821_signed. This is the model a fully-automated reseller uses.

# multipart/form-data
file:          <signed PDF, application/pdf, max 10 MB>   (required)
request_token: your-loan-12345                            (required)
entity_id:     uuid          # or entity_name if the request has one entity
years:         "2022,2023,2024"   # optional override
form_type:     "1120S"            # optional override
{ "success": true,
  "entity": { "id":"uuid","name":"ACME Holdings LLC","status":"8821_signed",
              "signed_8821_url":"https://…1h-expiry…","years":["2022","2023","2024"],"form_type":"1120S" } }

B. Let ModernTax collect the signature

POST /api/intake/8821

Submit entities with signer details (CSV/XLSX file or JSON { entities: [...] }) and ModernTax generates a pre-filled 8821, e-mails the signer for signature, then proceeds automatically.

CSV columns: entity_name, tid, tid_kind, email, signer_first_name, signer_last_name, years, address, city, state, zip, form_type.

{ "request_id":"uuid","entities_created":12,"signature_requests_sent":12,"status":"8821_sent" }

Poll for results

GET /api/intake/transcript?token=<request_token>

Returns every entity's current status, 1-hour signed transcript URLs, and a compliance read.

{
  "request_id": "your-loan-12345",
  "status": "completed",              // collapses to "completed" | "pending"
  "request_status": "completed",      // raw: submitted | 8821_sent | 8821_signed | irs_queue | processing | completed | failed
  "completed_at": "2026-05-09T10:32:11Z",
  "entities": [{
    "entity_id":"uuid","entity_name":"ACME Holdings LLC","tid":"12-3456789","form_type":"1120S",
    "years":["2022","2023","2024"],"status":"completed",
    "signed_8821_url":"https://…1h-expiry…","signature_created_at":"2026-05-08T…",
    "transcript_urls":["https://…/2022-record-of-account.pdf", "…"],
    "transcript_html_urls":["https://…"],
    "compliance": {
      "severity":"WARNING",           // CRITICAL | WARNING | CLEAN  (max across forms)
      "flags":[{"type":"BALANCE_DUE","severity":"WARNING","message":"Account balance: $4,287.21"}],
      "financials":{"grossReceipts":1240000,"totalTax":42000,"accountBalance":4287.21,"accruedInterest":0,"accruedPenalty":0},
      "recent_transactions":[{"code":"150","explanation":"Tax return filed","date":"2024-04-12","amount":"42000"}]  // ≤10, newest first
    }
  }]
}

Structured JSON

GET /api/v1/transcripts/{entityId}/structured

Machine-readable parse of a completed entity — filings, per-year compliance, and an income baseline — for resellers who consume data rather than files. Same x-api-key auth. A companion GET /api/v1/transcripts/{entityId}/cross-reference compares declared vs. IRS-of-record values.

{ "entity": {…}, "filings": [{ "year":"2023","form":"1120S","filed":true,… }],
  "compliance": {…}, "income_baseline": {…} }

Enroll in monitoring

POST /api/intake/monitoring
{ "request_token":"your-loan-12345", "entity_name":"ACME Holdings LLC",
  "frequency":"annual",            // weekly | monthly | quarterly | annual | custom
  "custom_interval_days":365,      // required if frequency=="custom"
  "skip_initial_pull":true, "expires_at":"2031-05-09", "next_pull_date":"2027-04-15" }

Returns the created subscription. If skip_initial_pull=false (default) an immediate_pull is queued. An entity with an active/paused subscription returns 409 with the existing one.

Webhooks — push result delivery

Results are pushed to the webhook URL ModernTax provisions for your account during onboarding (there is no per-request callback_url field). Delivery fires when an entity's transcripts are completed. There is no separate event for intermediate steps like 8821 signed or IRS queued — poll for those.

Headers

Content-Type: application/json
User-Agent: ModernTax-Webhook/1.0
X-ModernTax-Signature: <hex HMAC-SHA256 of the raw body, keyed with your webhook secret>
The signature header is present only if a webhook secret has been provisioned for your account. If you require signed payloads, ask for a secret at onboarding and verify the signature constant-time before processing. There is no x-moderntax-event header.

Payload

Two formats are supported; your account is configured for one:

// files format
{ "request_token":"your-loan-12345", "status":"complete",   // partial | complete | error
  "files":[{ "file_id":"uuid","type":"record_of_account","year":"2023",
             "entity_name":"ACME Holdings LLC","html":"<…>","created_at":"…" }] }

// structured format
{ "request_token":"your-loan-12345","status":"complete","record_id":"uuid",
  "record_type":"account_transcript","generated_at":"…","entity":{…},"data":{…},"raw_html":"…" }

Retries

On any non-2xx response ModernTax retries up to 5 times with backoff: 10s, 30s, 90s, 5m, 15m.

Employment & income verification

A separate product for W-2/1099 verification. Same x-api-key scheme.

POST /api/webhook/employment-intake
GET /api/webhook/employment-result?token=<request_token>

Poll returns parsed employment_data instead of transcripts. Ask for the employment schema when provisioning.

Errors

StatusMeaning
400Validation error (bad TID, non-PDF upload, file > 10 MB, missing required field).
401Missing or invalid x-api-key.
402Account not enrolled in billing — a payment method / billing setup is required before ordering.
404request_token or entity not found for your account.
409Duplicate request_token, or an entity already has a monitoring subscription.
429Account request quota reached (body includes usage).

Rate limits

A cumulative request quota is enforced per account when configured. Exceeding it returns 429 with { "error": "...", "usage": { "used", "limit" } }. Quotas are set with your plan — contact sales to raise one.

System status

GET /api/public/status

No auth. Returns { "status": "ok" } when healthy — safe to poll for monitoring.

Pricing & quotas

API accounts are billed monthly via ACH (Mercury) or Stripe at your negotiated rates. Representative default tier:

ItemRate
Transcript pull (per entity — record-of-account + return transcript, up to 3 yrs)$39.99
Monitoring enrollment (one-time per entity)$19.99
Monitoring per-pull (billed only when fresh transcripts are delivered)$59.98
Entity pre-validation (filing-requirement check)$19.99

Setup fee and monthly minimums apply per contract; volume pricing above 100 pulls/month — contact sales@moderntax.io.

Security & compliance

For SOC 2 evidence or vendor questionnaires: security@moderntax.io.

Versioning

This document describes the v1 surface (the /api/intake/* endpoints and /api/v1/transcripts/*). Breaking changes land under a new version path; existing endpoints remain stable.