A developer generates BIR 2307 and 2316 PDFs from payroll data

The developer sends JSON values in one web request and gets back a sealed PDF of the official BIR form.

Payroll users keep reporting 2316s that will not generate and alphalist files that do not tally.

To reproduce an official form, developers place every box by hand.

Developers report finding no agency API, so teams scrape portals or upload by hand.

A developer building a payroll or accounting application has to turn database records into official government papers. Employers give BIR 2316 to employees at year-end and file BIR 1601-C for monthly withholding. Businesses also issue BIR 2307 certificates to suppliers and contractors every quarter, and prepare SSS R-3 and PhilHealth RF-1 contribution lists for their staff.

Every paper form has its own layout and rules. A Taxpayer Identification Number (TIN) goes into individual digit boxes, with a branch code when the form has room for it. Dates follow the order printed on that specific form. Peso amounts and centavos must line up at the printed decimal point, and some forms ask for capital letters or drop centavos on computed lines.

When a software team builds this layer on their own, they map coordinates box by box for every page. Whenever a user types a letter inside a TIN, leaves a required field blank, or sends more table rows than one page prints, the layout breaks. That turns into support tickets for the developer, who then has to inspect the data and rebuild the PDF.

A free account: It gives the developer a test API key for practice and a live API key for real forms.

A way to send web requests: The application or terminal uses standard HTTPS requests like curl to talk to the API.

The form number or name: The developer uses it to look up the form id, such as bir-2307 or bir-2316.

Payee or employee records: The application sends values like the TIN, name, dates and amounts as a JSON object.

A unique request id: Sending it in the Idempotency-Key header stops a network retry from making a second document or charge.

1. Get a test API key. The developer creates a free account from the account page or with a POST request to the account endpoint. The account page shows a test key that starts with pk_test_ and a live key that starts with pk_live_. The developer puts the test key in the Authorization Bearer header on their server. A test key allows up to 500 free test PDFs a month, and each one is stamped TEST - NOT FOR FILING.

2. Read the form parameters. Before writing the fill code, the developer searches for the form id and fetches its parameter list. A GET request to the parameters endpoint for bir-2307 or bir-2316 returns every box on the paper. Each parameter gives the key name to send, the label printed on the form, and the type such as text, date or amount. This replaces measuring pixel coordinates by hand.

3. Check the answers first. The application sends the JSON values to the check endpoint before making a PDF. A check is free, needs no API key, and uses none of the monthly quota. If a TIN has letters or a value cannot fit on the paper, the response returns an issue list naming the exact field, code and expected format. The developer can also add compute=1 to let the form work out its own arithmetic on supported forms like BIR 2316 and BIR 1601-C.

4. Send the fill request. Once the values pass the check, the server sends the same JSON body in a POST request to the fill endpoint with the API key. The developer sends dates, TINs and peso amounts the way the database already stores them, without formatting them for the boxes. PhilForms lines up the digits, dates and centavos on the official form and returns the filled PDF bytes. Response headers tell the code the document id, how many boxes were filled, and whether every core field is complete.

5. Revise or replay for free. If a user spots a typo after generating a PDF, the developer sends a full re-fill with the first document id in the revise query parameter. An edit is free within 7 days for up to 5 edits, as long as it is the same form and the same filer ID, such as the payee TIN on BIR 2307. If a request times out and the server retries with an Idempotency-Key header, or sends the exact same values again in the same calendar month, it costs 0 credits.

Putting a live key in browser code. A live key starts with pk_live_ and spends credits from the account plan. It must stay on the developer’s server, never in public browser code; for a form on a website, use a site key that starts with pk_embed_.

Sending only the changed field on an edit. Using the revise parameter is a full re-fill, not a patch. If the code sends only the corrected field, every other box on the new PDF will come back blank, so the developer must send every value the form should carry again.

Misspelling a parameter name in the JSON. A key that is a one- or two-letter typo of a real parameter, like payeeTin instead of payee_tin, is refused with a 400 error and an unknown_parameter code. The developer can read the did_you_mean hint in the response and rename the key, or add strict=1 to refuse any unknown key.

Paying for an incomplete PDF by accident. A fill that leaves core fields blank still makes a sealed PDF and costs 1 credit. To prevent this, the developer can add require=core to the fill address so the call is refused with a free 400 error whenever a core field is missing.

The application receives the official form as an application/pdf response with every value printed in its box. On paid plans, answers are printed as real text that a user can select and search, while the Free plan and trial print a sharp image. Every PDF carries a document id in the X-Document-Id header, a cryptographic seal, a digital signature over every byte, and a ledger fingerprint. Anyone who receives the file can check that it is genuine and unchanged by sending the PDF bytes to the verify endpoint or dropping it on the verify page.

PhilForms only generates the filled PDF; it never files anything with the government. The developer’s application still has to deliver the PDF to the employer, bookkeeper, payee or employee. Those people review the printed numbers, add any required signatures by hand or through their workflow, and submit the form or file to the BIR, SSS or PhilHealth.

This API only fills PDF forms. It does not generate BIR alphalist DAT files, and it does not track or calculate changing SSS, PhilHealth or Pag-IBIG contribution tables from agency circulars. Developers also report that agencies offer no official APIs, and PhilForms does not submit returns to government portals or scrape agency websites. It also does not handle BIR system or printer accreditation for POS and invoicing software.

How can a developer test BIR 2307 and 2316 PDF generation for free?

Every free account comes with a test API key that starts with pk_test_. A developer can generate up to 500 test PDFs a month at 0 credits, and each file is stamped TEST - NOT FOR FILING. The check endpoint is also free and needs no key. For clean PDFs without a watermark, a Free account includes 5 clean BIR 2307 certificates a quarter, 5 clean BIR 2316 certificates a year, and a 30-day Pro trial with 500 credits that can be started until February 28, 2027.

Do I need to format TINs, dates and peso amounts before sending them to the API?

No, you send values the way your database already keeps them. You can send a date as 2026-01-15, 01/15/2026 or January 15, 2026, and it goes into the form’s boxes in the right order. A TIN like 123-456-789-000 is placed one digit per box, and an amount like 12500 is lined up as pesos and centavos at the printed decimal point.

What happens if my payroll server times out and retries a fill request?

You will not be charged twice. If you send an Idempotency-Key header up to 200 characters, repeating the same key and body replays the exact same PDF and document id at 0 credits. Even without that header, sending the exact same values for the same form in the same calendar month is treated as a free repeat.

Can the API calculate the tax lines on BIR 2316 and BIR 1601-C?

Yes, for lines where the form itself prints the arithmetic rule. If you add compute=1 to the check or fill address, or send is_compute set to true in the option object, the API fills the computed lines that you left blank. It covers BIR 1700, 1701, 1701A, 1701Q, 1601-C, 1601-EQ, 2316, 2550Q, 2551Q and 0605, and returns any limit or mismatch warnings in the response.

How do we fix a typo on a BIR 2307 after the PDF is made?

Send a POST request to the fill endpoint with the original document id in the revise query parameter, and include all values for the form again. The edit costs 0 credits if it is made within 7 days of the first fill, has fewer than 5 edits, uses the same kind of key, and keeps the same payee TIN.