curl --request POST \
--url https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm \
--header 'Authorization: <api-key>'import requests
url = "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm"
headers = {"Authorization": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<api-key>'}};
fetch('https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"annualReportId": "2Ns8vJqZ1lQwErTyUiOpAsDfGhJ",
"doolaCompanyId": "2Ns8vJqZ1lQwErTyUiOpAsDfGhJ",
"fiscalYear": 2026,
"state": "WY",
"entityType": "LLC",
"status": "FILLED",
"priceInCents": 6225,
"submittedAt": "2026-03-01",
"createdAt": "2026-02-01T09:00:00Z",
"updatedAt": "2026-02-02T09:00:00Z",
"answers": [
{
"fieldId": "Q17",
"value": "1000000"
}
],
"isReplaced": false
}Confirm an annual report and hand it to doola to file
Hands the report to doola to file and starts the work. Call this for every report, including one whose priceInCents is 0: a state that charges nothing still has a report to file, and confirming is what starts the work. Until you do, the report stays at FILLED and nothing happens to it. Call it on your own timing — an unconfirmed report waits indefinitely. Nothing is charged here and no card is debited: the priceInCents fixed at submission is the state fee doola settles with you under your partner agreement, outside this API. Safe to repeat: a report already confirmed is returned unchanged and is never handed over twice.
curl --request POST \
--url https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm \
--header 'Authorization: <api-key>'import requests
url = "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm"
headers = {"Authorization": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<api-key>'}};
fetch('https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm")
.header("Authorization", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.test.doola.com/v1/partner/companies/{companyId}/compliance/annual-reports/{annualReportId}/confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"annualReportId": "2Ns8vJqZ1lQwErTyUiOpAsDfGhJ",
"doolaCompanyId": "2Ns8vJqZ1lQwErTyUiOpAsDfGhJ",
"fiscalYear": 2026,
"state": "WY",
"entityType": "LLC",
"status": "FILLED",
"priceInCents": 6225,
"submittedAt": "2026-03-01",
"createdAt": "2026-02-01T09:00:00Z",
"updatedAt": "2026-02-02T09:00:00Z",
"answers": [
{
"fieldId": "Q17",
"value": "1000000"
}
],
"isReplaced": false
}Authorizations
Partner API key. Send the raw key as the Authorization header value — e.g. dk_test_… in sandbox or dk_live_… in production. Generate and rotate keys in the doola Partner Portal.
Path Parameters
doola company ID (KSUID).
Annual report ID (KSUID).
Response
The report is confirmed, or already was. Its status is IN_PROGRESS: doola is working it. A company that did not already hold the annual state filing service is granted it here.
An annual report on record.
Annual report ID (KSUID). Keep it: confirm and the status reads address the report by it.
"2Ns8vJqZ1lQwErTyUiOpAsDfGhJ"
doola company ID (KSUID).
"2Ns8vJqZ1lQwErTyUiOpAsDfGhJ"
Fiscal year the report covers.
2026
US state the report is filed in.
"WY"
Entity type the report was filed for.
LLC, CCorp "LLC"
Where the report stands.
FILLED, IN_PROGRESS, AWAITING_INFORMATION, FILING_COMPLETED "FILLED"
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.
6225
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.
"2026-03-01"
When the report was first recorded. Null if the row carries no timestamp.
"2026-02-01T09:00:00Z"
When the report last changed. Null if the row carries no timestamp.
"2026-02-02T09:00:00Z"
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.
Show child attributes
Show child attributes
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.
false