---
title: "Submit a company's annual report"
method: POST
path: "/v1/partner/companies/{companyId}/compliance/annual-reports"
tags: ["Annual Report Filing"]
---

# Submit a company's annual report

`POST /v1/partner/companies/{companyId}/compliance/annual-reports`

## Request

- Base URL: `https://api.test.doola.com`
- URL: `https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports`
- Auth: API key in header `Authorization`

Records the annual report in one call. Send the answers to every field /requirements published for the company, and only those - a field it was not offered is refused rather than ignored. This does not start the filing: the report rests at FILLED until you call /confirm, and waits there indefinitely. A report already on file for the year is replaced while it is still unconfirmed, and answers 409 once it is being worked on.

## Path parameters

- `companyId` string, required

## Request body

- PartnerAnnualReportSubmissionRequest: An annual report to file, supplied whole.
  - `fiscalYear` integer, nullable: Fiscal year the report covers. Defaults to the current year when omitted.
  - `answers` PartnerAnnualReportAnswerDto[], nullable: One entry per question the requirements published. Omit for a state that asks none, which is most of them.
    - `fieldId` string, required: The field's fieldId from the requirements response, as published in fields[].fieldId.
    - `value` string, required: The answer, as text. Typed against the field's own type before it is accepted.
  - `companyDetails` PartnerAnnualReportCompanyDetailsDto: Corrections to the company details doola already holds.
    - `companyName` string, nullable: Company name as it should appear on the report.
    - `address` PartnerAddressDto: A postal address.
      - `id` string: Server-assigned ID.
      - `line1` string, required: Street address line 1.
      - `line2` string: Street address line 2.
      - `city` string, required: City.
      - `state` string, required: State or province.
      - `postalCode` string, required: Postal or ZIP code.
      - `country` string, required: ISO 3166-1 alpha-3 country code (e.g. USA).
      - `phone` string: Phone number in E.164 format. Required for a person's address (the responsible party, a member, or an executive member); optional for a company `mailing` or `business` address.
    - `mailingAddress` PartnerAddressDto: A postal address.
      - `id` string: Server-assigned ID.
      - `line1` string, required: Street address line 1.
      - `line2` string: Street address line 2.
      - `city` string, required: City.
      - `state` string, required: State or province.
      - `postalCode` string, required: Postal or ZIP code.
      - `country` string, required: ISO 3166-1 alpha-3 country code (e.g. USA).
      - `phone` string: Phone number in E.164 format. Required for a person's address (the responsible party, a member, or an executive member); optional for a company `mailing` or `business` address.
    - `physicalAddress` PartnerAddressDto: A postal address.
      - `id` string: Server-assigned ID.
      - `line1` string, required: Street address line 1.
      - `line2` string: Street address line 2.
      - `city` string, required: City.
      - `state` string, required: State or province.
      - `postalCode` string, required: Postal or ZIP code.
      - `country` string, required: ISO 3166-1 alpha-3 country code (e.g. USA).
      - `phone` string: Phone number in E.164 format. Required for a person's address (the responsible party, a member, or an executive member); optional for a company `mailing` or `business` address.
    - `phoneNumber` string, nullable: Phone number. Required for a Delaware C-corp, which doola does not hold one for.
    - `authorizedShares` number, nullable: Authorized shares. A whole number.
    - `issuedShares` number, nullable: Issued shares. A whole number.
    - `perValuedShares` number, nullable: Par value per share, in USD.

## Response `200`

The report is on file and replaced an unconfirmed one for the same fiscal year; same annualReportId, isReplaced true.

- PartnerAnnualReportFilingResponse: An annual report on record.
  - `annualReportId` string: Annual report ID (KSUID). Keep it: confirm and the status reads address the report by it.
  - `doolaCompanyId` string: doola company ID (KSUID).
  - `fiscalYear` integer: Fiscal year the report covers.
  - `state` string: US state the report is filed in.
  - `entityType` 'LLC' | 'CCorp': Entity type the report was filed for.
  - `status` 'FILLED' | 'IN_PROGRESS' | 'AWAITING_INFORMATION' | 'FILING_COMPLETED': Where the report stands.
  - `priceInCents` integer: The state fee for this report in whole US cents, fixed when it was recorded. Nothing is charged through this API. 0 where the state charges nothing.
  - `submittedAt` string, nullable: Date the report was handed to doola's filing pipeline (yyyy-MM-dd). Null on a report that has only just been recorded; read status for where the report stands.
  - `createdAt` string, date-time, nullable: When the report was first recorded. Null if the row carries no timestamp.
  - `updatedAt` string, date-time, nullable: When the report last changed. Null if the row carries no timestamp.
  - `answers` PartnerRecordedAnswerDto[]: The answers on record, addressed by the field ids the requirements published. Empty for a state that asks no questions, which is most of them.
    - `fieldId` string: Field id, as published by the requirements endpoint's fields[].fieldId. An answer stays on record under it after doola stops asking that question, so it may name a field the requirements no longer publish.
    - `value` string, nullable: What was answered, as given.
  - `isReplaced` boolean: True when a report was already on file for this year and this one took its place, which is allowed only while the report is still FILLED.

## Other responses

- `201`: The report is on file, newly created for this fiscal year.
- `400`: E_VALIDATION_FAILED: an answer or a correction was not one this company was offered, was missing, or was not the kind of value its field asks for. The refused field is reported under error.fields, keyed by its fieldId.
- `404`: E_COMPANY_NOT_FOUND: the company does not exist, or is not owned by the calling partner.
- `409`: E_ANNUAL_REPORT_ALREADY_EXISTS: a report is on file for this company and fiscal year that must not be overwritten, because it has been confirmed, filed, or is being worked on.
- `422`: E_STATE_NOT_SUPPORTED: the company's state files no annual report, so there is nothing to submit.

## Changes

- **2026-11-03** `f607744a8927`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/doola/apis/doola-partner-api/changes/v1/partner/companies/:companyId/compliance/annual-reports/post.md)

---

[API](https://skmtc.dev/doola/apis/doola-partner-api.md) - [All operations](https://skmtc.dev/doola/apis/doola-partner-api/llms.txt) - [OpenAPI document](https://skmtc.dev/doola/apis/doola-partner-api/revisions/f607744a8927?raw)
