> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doola.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Authenticate with the raw API key in the Authorization header. Never add a Bearer prefix.
> Use the sandbox base URL https://api.test.doola.com and a dk_test_ key in examples unless the user asks for production.
> Send an Idempotency-Key header on POST /v1/partner/customers and POST /v1/partner/companies. No other endpoint takes one.
> Every response is wrapped as {payload, error}. Read fields from payload and branch on error.code, never on the message.
> Drive formation progress from webhooks plus a reconciliation sweep, never a polling loop.
> Embedded SDK (@doola/js): the dk_ key stays on the server and mints customer sessions; the browser gets only a pk_ key and the session. onFormed carries only companyId and can fire more than once. Before charging, read the company with the dk_ key, require formationSubmissionStatus AWAITING_PAYMENT, check the owner's email, and price on the server. Then POST payment-confirmed, which answers 200 with an empty body, and replace the SDK element with a new doola.create() (never append a second one).
> The doola Formation MCP server at https://mcp.doola.com is for founders forming their own company with their own doola account. Partners integrate the Partner API or the Embedded SDK. The /mcp endpoint on this docs site only searches these docs.
> For a full capability summary with the rules above, read https://docs.doola.com/skill.md.

# Annual report correction

> Handle ANNUAL_REPORT_ADDRESS_NOT_ACCEPTED and ANNUAL_REPORT_SHARE_VALUE_TOO_HIGH by sending back the company details the state refused.

doola files a company's annual report with the details it holds. Sometimes the state will not take them: it refuses the registered agent's address as the company's own, or the authorized share count multiplied by the par value lands above the threshold the state prices from, which adds fees to the report. Rather than file something that will be rejected or overcharged, doola raises a required action on the company, puts the report into `AWAITING_INFORMATION`, and waits for you.

Two codes do this, and you answer both the same way.

| Code | Raised when | Fields it asks back for |
| - | - | - |
| `ANNUAL_REPORT_ADDRESS_NOT_ACCEPTED` | The state does not accept the registered agent's address as the company's own address on the report | `address` |
| `ANNUAL_REPORT_SHARE_VALUE_TOO_HIGH` | Share count times par value exceeds the state's pricing threshold | `authorizedShares`, `perValuedShares` |

Do not hardcode that third column. Each action publishes what it wants in `requestedFieldIds`, and that list is the contract. See [Reading what is asked](#reading-what-is-asked).

You are told by the `company_annual_report_info_required` webhook, which both codes use. See [Required actions](https://docs.doola.com/api/required-actions.md) for the payload, the status model, and how to read actions back.

> [!NOTE]
>
> These actions are about a report doola is filing for the company. They are unrelated to a report you submitted yourself through [Annual Report Filing](https://docs.doola.com/api/compliance/annual-report-filing.md) and have not confirmed; that one you correct by submitting it again.

## The flow

```mermaid theme={null}
sequenceDiagram
    participant P as Your backend
    participant D as doola API

    Note over D: Report ready to file
    D->>D: State refuses the details on file
    D-->>P: webhook company_annual_report_info_required
    Note over D: Report held at AWAITING_INFORMATION
    P->>D: Read the action, see requestedFieldIds
    P->>D: Submit resolution with companyDetails
    D-->>P: 200, action status submitted
    D->>D: Report returns to Ops to be filed
```

The report stays at `AWAITING_INFORMATION` while the action is still waiting on you. That is `awaitingResponse`, not `open`. Submitting clears it and the report moves on once no other correction on that report is still waiting (see [After you submit](#after-you-submit)), while the action itself stays open. Nothing is filed with the state and no `company_annual_report_completed` fires until doola has filed the corrected report.

## Reading what is asked

Read the action before answering it. `requestedFieldIds` names the fields this action wants, spelled as [the annual report requirements](https://docs.doola.com/api/compliance/annual-report-filing.md#requirements-what-to-collect) spell them:

```bash theme={null}
curl https://api.test.doola.com/v1/partner/companies/{companyId}/required-actions/{requiredActionId} \
  -H "Authorization: dk_test_your_api_key_here"
```

```json theme={null}
{
  "payload": {
    "requiredActionId": "31wR7kM2nP5qT8vXyZaBcDeFgHj",
    "actionCode": "ANNUAL_REPORT_ADDRESS_NOT_ACCEPTED",
    "actionName": "New business address needed",
    "reason": "The state does not accept the registered agent's address as the company's own address on the annual report. Provide a different business address.",
    "requestedFieldIds": ["address"],
    "status": "delivered",
    "open": true,
    "awaitingResponse": true
  },
  "error": null
}
```

Render `reason` to your user verbatim; it is written for a person and says which state refused what.

## Sending the correction

Post to the [resolution endpoint](https://docs.doola.com/api/required-actions/name-options.md#submitting-new-names) with the action's code and a `companyDetails` object keyed by the field ids the action named.

```bash theme={null}
curl https://api.test.doola.com/v1/partner/companies/{companyId}/required-actions/{requiredActionId}/resolution \
  -X POST \
  -H "Authorization: dk_test_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "actionCode": "ANNUAL_REPORT_ADDRESS_NOT_ACCEPTED",
    "companyDetails": {
      "address": {
        "line1": "251 W 30th St",
        "city": "New York",
        "state": "NY",
        "postalCode": "10001",
        "country": "USA"
      }
    }
  }'
```

For a share value action, send the figures instead:

```json theme={null}
{
  "actionCode": "ANNUAL_REPORT_SHARE_VALUE_TOO_HIGH",
  "companyDetails": {
    "authorizedShares": 1000,
    "perValuedShares": 0.0001
  }
}
```

**Send what the action asked for and nothing else.** `companyDetails` accepts the full vocabulary of company detail fields, but a field this action did not name is refused with `400 E_VALIDATION_FAILED`. Answering an action is not a channel for rewriting details nobody asked about; those go through the endpoints that own them. A field the action *did* name and you leave out keeps the value doola already holds, so send every field you want changed in one call.

## After you submit

The response is the action at `submitted`, not `resolved`.

> [!WARNING]
>
> `submitted` is not done, and it is not the end of the action either. Your answer is on file and the report has gone back to doola's filing queue, but the action stays `open` until Ops close it by hand. Filing the report fires `company_annual_report_completed` and leaves the action open. Wait for that event, never for `open: false`, before telling your user the matter is settled.

Two things are worth knowing about what happens next.

**Ops can have two corrections open on the same report**, one per code. Answering one of them does not move the report: it goes back to the filing queue only when the last outstanding correction on that report has been answered. An action on a *different* report of the same company is independent and does not hold yours back, as long as both name their report. If either names none, the two cannot be told apart, so doola falls back to treating every open correction on the company as blocking. That delays a hand-back rather than risking two.

**A correction never changes what you were charged.** The price of an annual report is fixed when the report is priced, and the money is already taken. Lowering a share count through this action corrects what gets filed with the state; it does not reprice the report or trigger a refund. If the figures you send should have produced a lower price, raise it with doola rather than expecting the API to settle it.

## Errors

| HTTP | Code | Meaning |
| - | - | - |
| 400 | `E_VALIDATION_FAILED` | `companyDetails` is missing, empty, or carries a field this action did not name. `error.fields.companyDetails` carries a message naming the field |
| 409 | `E_ANNUAL_REPORT_NOT_CORRECTABLE` | No annual report on this company can take this correction right now |

`E_ANNUAL_REPORT_NOT_CORRECTABLE` does not mean the company has no reports. It covers every way the correction cannot land right now:

* The report the action names is no longer `AWAITING_INFORMATION`.
* The action names no report and the company has none awaiting, or more than one, so there is nothing to pick.
* The report still reads as awaiting, but the underlying ticket moved on: filed, closed as unresponsive, or put back on the customer's payment.

The action being open is not a promise that the report is still correctable. Treat this as terminal rather than retrying it, and read the company's reports to see where the year actually got to.

The [full error table](https://docs.doola.com/api/required-actions.md#errors) lists the codes any resolution can return.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.