Notice response
A letter from the IRS, answered. The AI reads it, your code matches each payment against the periods the letter shows, and sorts it. A representative claims it, the officer grants a Form 2848 that names them by CAF number for this form and these periods, and the response goes out under it. Or, for $99, the officer answers it herself.
tax's wordsreturn is a jobtaxpayer is a subjectreview is a taskpreparer is a member
A corporation's notice is usually about money: a balance due, a payment posted to the wrong period, or a penalty. The Notice Response reads the letter, finds the facts in the taxpayer's own payments, and answers through a representative under a grant that names them.
$ cat services/notice-response.ts
import { Service } from 'services.dev'
import { classify, matchPayments } from '../lib/tax.ts'
import { preparers } from '../pools/preparers.ts'
import rules from '../rules.ts'
// A letter from the agency, answered. The AI reads it, your code matches each payment the taxpayer kept against the
// periods the letter shows them posted to, and sorts it: pay what is owed, ask for a misapplied payment to be moved, ask
// for a penalty to be abated, or reply. A representative claims it, and only then is the officer asked for a Form 2848
// that names them by CAF number, for this form and these periods, for a year, withdrawn once the reply is accepted. The
// reply date is the representative's to answer for. For $99 the officer answers it themselves, in their own name. On an
// abatement, a quarter of the penalty taken off is the fee, $99 at least. A letter asking for more time to assess gets
// the officer's signature on a Form 872, and the date it sets is kept on the taxpayer, so the year's clocks move to it.
export default Service({
name: 'Notice Response',
| Key | Here | What it does |
|---|---|---|
match | matchPayments, your code | Lists each payment the brand holds a receipt for, the period it was for, and the period the letter shows it posted to |
classify | routes by kind | Agree and pay; a misapplied payment, a penalty to abate, or anything else, to the representative |
respond.drafts | by kind | The AI drafts a transfer request citing the receipt, or a request to abate, for the representative to stamp |
poa.after | 'respond.claim' | The grant is asked only once a representative claims, so it can name them |
poa.what, poa.names | 'Form 2848', { claimant: 'caf' } | The authorization names the representative who claimed, by CAF number |
poa.scope | represent and send, income tax, Form 1120, the letter's periods, 365 days | The acts, the matter and the span it gives |
poa.withdrawn | ['accepted', 'for'] | Withdrawn once the reply is accepted, or when its span runs out |
needs | 'poa', on respond and send | The gate refuses the step needs_grant until the grant is live |
clocks.reply | due reply_by, owned by the representative | Ten days out a notice, five days out the rung that asks the IRS for more time |
price.self, price.outcome | 99; 25% of a penalty abated, $99 at least | The officer answers it herself, or the fee rides on what is taken off |
Here it's ordered on its own.
npx services.dev check --routes services/notice-response.ts agree the balance is right → pay · the owner pays it, or you route it to the Treasury · CP161
misapplied a payment posted wrong → respond · a transfer request, citing the receipt · CP161 on a period the brand paid
penalty a penalty to take off → respond · a request to abate · 25% of what is taken off, $99 at least · CP162, CP215
respond anything else → respond · the representative's reply · a letter asking for recordsThe letter says Acme owes $76,289.85 for 2026. The match finds why: the extension's deposit was posted to 2027:
→ POST /returns {"service":"notice-response","owner":{"name":"Ada Lovelace","email":"ada@example.com"},"ein":"12-3456789","notice":"cp161.pdf","reply_by":"2027-12-14","tax_years":["2026","2027"],"max_usd":299,"key":"cp161"}← job_4Tx2 · waiting · on claim · $299.00 held · respond · tsk_7Hq2
read CP161 · balance due $76,289.85 for 2026: tax $73,710.00, failure-to-pay penalty $2,579.85 · reply by 2027-12-14
match rcp_7HqB · US $73,710.00 · Form 7004 for 2026, paid 2027-04-12 · posted to 2027
classify misapplied → respond, to draft a transfer request citing rcp_7HqBKatherine Johnson claims the review. Only then is Ada asked for the Form 2848, naming Katherine by CAF number, for Form 1120 and both periods:
→ GET /asks/ask_7Hq2?t=…← 200 ask_7Hq2 · poa · to grant · Form 2848 · Ada Lovelace · open
names Katherine Johnson · enrolled agent · CAF 0312-45678R · PTIN P01234568
matters income · Form 1120 · 2026, 2027
acts represent, send · for 365 days · withdrawn when the reply is acceptedResponding needs the grant live, and Ada hasn't given it yet:
→ POST /practitioners/returns/job_4Tx2/approve {"checklist":[]}← 403 needs_grant: respond needs the poa grant live, and the party hasn't given it yet.She grants it, e-signed:
→ POST /asks/ask_7Hq2?t=… {}← 200 done
← job_4Tx2 · waiting · on person · $299.00 held · respond · tsk_7Hq2Katherine stamps the transfer request, and it's sent under the grant:
→ POST /practitioners/returns/job_4Tx2/approve {"checklist":[]}
← job_4Tx2 · delivered · $299.00 charged
grants [{"step":"poa","form":"2848","names":{"member":"mbr_8Ea1","caf":"0312-45678R"},"scope":{"acts":["represent","send"],"matters":[{"tax":"income","form":"1120","periods":["2026","2027"]}],"for":"365d"},"status":"live","until":"2028-11-13T15:00:00.000Z","withdrawn_on":"accepted"}]→ GET /owner/returns/job_4Tx2 # the owner console record read · ai · CP161 | match · code · rcp_7HqB posted to 2027 | classify · code · misapplied → respond | review · ai · pass | respond · claimed · mbr_8Ea1 | poa · asked · names mbr_8Ea1, CAF 0312-45678R | respond · representative · refused · needs_grant · respond needs the poa grant live, and the party hasn't given it yet. | poa · owner · Form 2848 · esign | respond · person · enrolled agent · * · mbr_8Ea1 · a transfer request citing rcp_7HqB · stamped | send · the agency · accepted · rcp_7Hq2
clocks reply · due 2027-12-14 · mbr_8Ea1 · satisfied · its request-time rung, 5 days out, never needed
ledger +$299.00 · AI $0.84 · representative $90.00 · you $208.16With posture: 'self', the AI drafts the same response, Ada signs and sends it herself, and the grant is skipped. It costs $99. On a penalty the IRS takes off, the fee is a quarter of what is abated: the money.
Grants and decisions covers scope, needs and revoking a grant. In the year, the plan mints this Service from a November notice.