[AR] Withholdings and perceptions: /tax-id-validations + /sales and /transfers
In Argentina, a company designated as a collection agent has two jobs:
- Perceptions (percepciones). When it sells, it charges extra tax to the customer.
- Withholdings (retenciones). When it pays a supplier or settles funds to a merchant, it keeps part of the payment.
Rates are set by ARCA and by each province, and they change per counterpart and per month through the padrones.
This guide shows the practical flow:
- Validate the counterpart's CUIT with
/tax-id-validations. Brinta stores their tax condition and padrón rates. - Send the operation:
/salesfor perceptions;/transfersfor withholdings.
- Brinta applies the right taxes, rates, bases and minimums.
You never send rates or padrón data yourself.
API reference: Create a company · Tax ID validation · Get a validation · Tax ID validation for Argentina · Create a sale · Create a transfer · Company codes
sequenceDiagram
participant You
participant Brinta
participant Sources as ARCA + provincial padrones
You->>Brinta: POST /companies (counterpart CUIT)
You->>Brinta: POST /tax-id-validations (company_id, update_company: true)
Brinta->>Sources: Identity, IVA condition, padrón lists
Brinta-->>You: webhook validation.succeeded
You->>Brinta: GET /tax-id-validations/{id}
Note over Brinta: Tax condition and padrón rates stored on the company
You->>Brinta: POST /sales (buyer.company_id) → perceptions
You->>Brinta: POST /transfers (counterpart.company_id) → withholdings
What decides each tax
| Input | Where it comes from |
|---|---|
| Whether you are an agent for a regime (for example ARBA perception agent, RG 830 withholding agent) | Your company's configuration in Brinta. Your account manager enables it. It is not a request field. |
Counterpart's IVA condition (Responsable inscripto, Responsable monotributo, Exento, No categorizado, IVA no alcanzado) | /tax-id-validations, stored as the status of the counterpart's CUIT. |
| Counterpart's padrón rate per jurisdiction, exclusions, Convenio Multilateral or local status | /tax-id-validations, stored as registry-list memberships on the counterpart, each with its validity and rate. |
| Jurisdiction | Counterpart address (state, ISO 3166-2, for example AR-C), physical_address, or an item location category ({ "list": "location", "code": "AR-C" }). See Step 3. |
| Activity or concept | Item categories, for example an activity code on sales or the RG 830 concept on payments. |
| Date | invoice_date on sales, transaction_date on transfers. Padrón memberships are applied only if valid on that date. |
| Minimums | Configured per regime. Brinta drops the tax when the operation is below the regime's minimum. |
Step 1: Create the counterpart
Reference: Create a company.
curl -X POST https://api.brinta.com/companies \
-H "Authorization: Bearer $BRINTA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "business",
"legal_name": "Cliente Ejemplo SA",
"external_id": "CUST-30710455259",
"address": { "country": "AR", "state": "AR-C" },
"tax_registrations": [
{ "number": "30710455259", "type": "CUIT", "level": "country", "location": "AR" }
]
}'Keep the returned id. You'll use it in every validation and transaction for this counterpart.
Step 2: Validate the CUIT
Reference: Tax ID validation and Tax ID validation for Argentina, which lists what Brinta checks at national and provincial level.
curl -X POST https://api.brinta.com/tax-id-validations/ \
-H "Authorization: Bearer $BRINTA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"company_id": "456c6c4f-f64a-4069-9988-8164c015cf80",
"update_company": true,
"locations": ["AR"]
}'| Field | Notes |
|---|---|
company_id / company_external_id | The company to validate. Results are written to it only when update_company is true. |
update_company | true stores the IVA condition, activities and padrón memberships on the company, so later sales and transfers use them. With false you get the result back, but nothing is stored. |
locations[] | The countries (ISO 3166-1, for example "AR") or provinces (ISO 3166-2, for example "AR-C") to validate in, as plain strings: ["AR"] or ["AR", "AR-C"]. This is the same format as location in tax_registrations. |
periods | Optional, ["YYYY-MM"]. The months to check padrones for. Defaults to the current month. Use it to load next month's padrón once it's published, or to rebuild a past month. |
To check a CUIT without creating a company, send company instead of company_id. Nothing is stored in that case:
{
"locations": ["AR"],
"company": {
"type": "business",
"legal_name": "Empresa Test SIRTAC",
"tax_registration": { "number": "20123456789", "type": "CUIT", "level": "country", "location": "AR" }
}
}Getting the result
The validation runs asynchronously. The POST answers immediately:
{ "id": "tiv2-188be839-bd78-4692-9fd4-53e67e2d28bc", "status": "in_process" }When it finishes, Brinta sends the validation.succeeded (or validation.failed) webhook. Then read it with Get a validation:
curl https://api.brinta.com/tax-id-validations/tiv2-188be839-bd78-4692-9fd4-53e67e2d28bc \
-H "Authorization: Bearer $BRINTA_TOKEN"{
"id": "tiv2-188be839-bd78-4692-9fd4-53e67e2d28bc",
"status": "succeeded",
"data": [
{
"locationIsoCode": "AR",
"status": "succeeded",
"company": {
"legal_name": "Cliente Ejemplo SA",
"tax_registrations": [
{ "number": "30710455259", "type": "CUIT", "level": "country", "location": "AR",
"status": "Responsable inscripto", "authority": "AFIP", "activities": ["620900"] }
],
"address": { "state": "AR-C", "postal_code": "C1043" }
},
"registry_lists": [
{ "name": "percep_IIBB_CABA_Regimen_General_2.5", "type": "Padrón CABA Regimen General",
"country": "AR", "rate": 0.025, "valid_from": "2026-07-01T00:00:00.000Z", "valid_until": "2026-07-31T23:59:59.999Z" },
{ "name": "wht_IIBB_CABA_Regimen_General_2.5", "type": "Padrón CABA Regimen General",
"country": "AR", "rate": 0.025, "valid_from": "2026-07-01T00:00:00.000Z", "valid_until": "2026-07-31T23:59:59.999Z" },
{ "name": "padron_sirtac_CABA_0.05", "type": "Padrón SIRTAC",
"country": "AR", "rate": 0.0005, "valid_from": "2026-07-01T00:00:00.000Z", "valid_until": "2026-07-31T23:59:59.999Z" },
{ "name": "Convenio_Multilateral", "country": "AR",
"valid_from": "2026-07-01T00:00:00.000Z", "valid_until": "2026-07-31T23:59:59.999Z" }
]
}
]
}Reading registry_lists
registry_listsEach entry is one padrón the CUIT belongs to, for one period.
| Name pattern | Meaning |
|---|---|
percep_IIBB_<jurisdiction>_..._<rate> | IIBB perception rate for this customer in that jurisdiction. Examples: percep_IIBB_CABA_Regimen_General_2.5, percep_IIBB_ARBA_<letter>_<rate>, percep_IIBB_SantaFe_<rate>. |
wht_IIBB_<jurisdiction>_..._<rate> | IIBB withholding rate for this supplier or merchant in that jurisdiction. Examples: wht_IIBB_CABA_Regimen_General_2.5, wht_IIBB_Cordoba_<rate>. |
padron_sirtac_<province>_<rate> | SIRTAC rate per province. |
Convenio_Multilateral, Convenio_Multilateral_AR-X, Contribuyente_Local_AR-X | Registered under Convenio Multilateral, or as a local taxpayer in a province. |
Exclusion_IVA, Exclusion_Ganancias, Exclusion_wht_IVA, Exclusion_wht_Ganancias, exclusion_perc_IBB_AR-S, IIBB_<province>_Exento | Exclusions and exemptions. While valid, the matching tax is not applied. |
percep_IVA_ARCA | IVA perception classification from ARCA. |
- The rate in the name is a percentage (
2.5= 2.5%). Theratefield is the same value as a fraction (0.025). - An empty
registry_listsmeans the CUIT is in none of the padrones checked. For many regimes that triggers the "out of padrón" rate (see the tables below), which is usually the highest.
Re-validate every month. Padrones are published monthly, and each membership is valid only for its period. A sale or transfer dated aftervalid_untilno longer sees the rate. Schedule a validation for each active counterpart when the new padrones come out. Useperiods: ["2026-08"]to load next month as soon as it's available.
Validating inside the transaction. If your account has it enabled, you can send"tax_id_validation": trueinsidebuyer(on/sales) orcounterpart(on/transfers). Brinta then validates the CUIT synchronously before calculating taxes, for the transaction's date. This is convenient for new counterparts, but it makes the request slower, and the request fails if the validation fails. Ask your account manager to enable it.
Certificates that aren't public. Some exclusion or reduction certificates don't appear in any public padrón. Your account manager can load them on the counterpart as a registry-list membership with its validity dates. See Company complementary information.
Step 3: Tell Brinta where the operation happens
IIBB is provincial, so the province decides which perceptions and withholdings apply. By default Brinta uses the counterpart's registered address, which is the state stored on the company. Validation fills it in from AFIP.
When the operation happens somewhere else, tell Brinta in one of two ways:
| Situation | Use |
|---|---|
| The whole operation happens in a single province that differs from the counterpart's address | physical_address on buyer (sales) or counterpart (transfers) |
| Items in the same transaction belong to different provinces | A location entry, { "list": "location", "code": "AR-X" }, in each item's categories |
Use one of the two per transaction.
The whole operation is in another province: physical_address
physical_addressExample: the buyer is registered in CABA, but the goods are delivered to their warehouse in Córdoba.
"buyer": {
"company_id": "456c6c4f-f64a-4069-9988-8164c015cf80",
"physical_address": {
"country": "AR",
"state": "AR-X",
"city": "Córdoba",
"postal_code": "X5000",
"address_line_1": "Av. Colón 1234"
}
}physical_addresssits next tocompany_id,company_external_idorcompany, and works with any of them.countryis required.state(ISO 3166-2) is what selects the provincial regimes. Brinta uses the most specific level you send.- It applies to this transaction only. The address stored on the company doesn't change.
- On
/transfers, send it ascounterpart.physical_address. For example, a supplier registered in CABA that rendered the service in Santa Fe. - On
/transfers, if you send a beneficiary bank account (payment_method.bank_account.beneficiary), the beneficiary's location is used instead.
Items in different provinces: the location category
location categoryExample: one invoice for implementation services delivered at two sites, one in CABA and one in Córdoba.
"items": [
{
"name": "Implementación - sede CABA",
"amount": 60000,
"categories": [ { "code": "82990" }, { "list": "location", "code": "AR-C" } ]
},
{
"name": "Implementación - sede Córdoba",
"amount": 40000,
"categories": [ { "code": "82990" }, { "list": "location", "code": "AR-X" } ]
}
]- Each item's provincial taxes are determined for its own province:
- the first line gets CABA's regime, using the buyer's CABA padrón rate;
- the second line gets Córdoba's regime.
- Country-level taxes, such as IVA and Percepción IVA, don't change.
- Send one
locationentry per item, next to the item's activity or product code. Use the province codes in the table below. - It works the same way on
/transfersitems. For example, a payment to a supplier for works carried out in two provinces.
Step 4a: Sales with perceptions
curl -X POST https://api.brinta.com/sales/ \
-H "Authorization: Bearer $BRINTA_TOKEN" \
-H "Content-Type: application/json" \
-H "x-idempotency-key: 4a3b2c1d-0e9f-4a8b-9c7d-6e5f4a3b2c1d" \
-d '{
"type": "sale",
"status": "pending",
"currency": "ARS",
"invoice_date": "2026-07-10T03:10:00.000Z",
"transaction_owner_company_id": "5c6e4b83-a032-11ee-a484-0a8bae22163d",
"transaction_external_id": "FAC-A-0003-00004567",
"document_type": "invoice",
"payment_method": { "type": "bank transfer" },
"buyer": { "company_id": "456c6c4f-f64a-4069-9988-8164c015cf80" },
"items": [
{
"name": "Servicios prestados durante julio 2026",
"amount": 100000,
"categories": [
{ "code": "82990" },
{ "list": "location", "code": "AR-C" }
]
}
]
}'transaction_owner_company_idis you, the seller. Your agent registrations decide which regimes are even considered.buyer.company_idis the validated customer. Their IVA condition and padrón rates are read from the company.invoice_datepicks the padrón period. Send the date of the invoice.invoice_dateis interpreted in UTC (UTC+0). Send it in ISO 8601 with the Z suffix and convert from local time before sending. For example, a sale made at 00:10 on July 10, 2026 in Argentina (UTC-3) must be sent as 2026-07-10T03:10:00.000Z.- The
locationcategory sets the province where the activity is taxed. See Step 3. The activity code (82990) drives the IVA rate and any activity-specific regime.
Response (abridged and illustrative). The seller is an IVA and CABA IIBB perception agent; the buyer is a Responsable inscripto in the CABA padrón at 2.5%:
{
"amount": 100000,
"final_amount": 126500,
"items": [
{
"amount": 100000,
"final_amount": 126500,
"taxes": [
{ "name": "IVA", "type": "VAT", "rate": 0.21, "taxable_amount": 100000, "amount": 21000,
"level": "country", "location": "AR", "adds_to_final_amount": true },
{ "name": "Percepción IVA", "type": "VAT", "rate": 0.03, "taxable_amount": 100000, "amount": 3000,
"level": "country", "location": "AR", "withholding_type": "PERCEPTION", "adds_to_final_amount": true },
{ "name": "Percepción IIBB - CABA", "type": "GIT", "rate": 0.025, "taxable_amount": 100000, "amount": 2500,
"level": "state", "location": "AR-C", "withholding_type": "PERCEPTION", "adds_to_final_amount": true }
]
}
]
}Perceptions have a positive rate and amount, withholding_type: "PERCEPTION", and are added to final_amount: the customer pays them. Print each one as a separate line on the invoice. If you issue the invoice through Brinta (POST /invoices with transaction_id), this happens automatically. For the invoice payload, see the [AR] invoice guide.
Perceptions Brinta determines (examples)
| Regime | Applies when | Rate source |
|---|---|---|
| Percepción IVA (general regime) | You are an IVA perception agent and the buyer is Responsable inscripto | 3% |
| Percepción IVA, No categorizado | Buyer is No categorizado | 10.5% on the amount plus IVA |
| Percepción IIBB Buenos Aires (ARBA) | You are an ARBA agent | Buyer's ARBA padrón rate (0% to 8%) × ARBA coefficient; 8% if not in the padrón |
| Percepción IIBB CABA (AGIP) | You are an AGIP agent | Buyer's CABA padrón rate (0% to 6%); 6% if not in the padrón |
| Percepción IIBB Santa Fe (RG 15/1997) | You are a Santa Fe agent | Buyer's Santa Fe padrón rate; 0% if excluded; 6% if not in the padrón |
| Percepción IIBB Tucumán | You are a Tucumán agent | Tucumán padrón rate and coefficient |
| Other provinces: Corrientes, Misiones, Salta, San Juan, San Luis, Chaco, Jujuy, La Pampa, Neuquén, Río Negro, Entre Ríos, Tierra del Fuego, Córdoba | As configured per province | Padrón rate, Convenio Multilateral or local status |
| Digital services regimes: AGIP RG 312/2019, ARBA RG 38/2019, Córdoba, Santa Fe and others | Cross-border digital services | Fixed rates (for example 2%) |
| Municipal: La Plata TISH, Córdoba RG 18, Posadas | As configured | Fixed rates |
Step 4b: Payments with withholdings
Use /transfers:
type: "payment from invoice"when you pay a supplier invoice. See Paying a supplier invoice.type: "to settle"when a platform pays out a merchant. See Settling funds to a merchant.
Paying a supplier:
{
"type": "payment from invoice",
"status": "created",
"currency": "ARS",
"transaction_date": "2026-07-10T03:10:00.000Z",
"account_holder_company_id": "82238834-db8c-4d87-b16e-2bd2b4fa473e",
"counterpart": { "company_id": "9a7d41f5-faae-4617-bc52-abaa5f3cae36" },
"items": [
{
"name": "Honorarios por servicios - junio",
"amount": 1000000,
"categories": [
{ "code": "out" },
{ "code": "94", "list": "rg_830" },
{ "list": "location", "code": "AR-C" }
],
"taxes": [
{ "name": "IVA", "tax_type": "VAT", "rate": 0.21, "taxable_amount": 1000000, "amount": 210000,
"tax_level_type": "country", "location": "AR" }
]
}
]
}- On this example
- The RG 830 concept goes in the item's
categories, with listrg_830. Code94is locaciones de obra y servicios. - Send the IVA printed on the invoice, so Brinta can build the gross payment amount.
- The supplier's IIBB withholding rate comes from their padrón membership, for example
wht_IIBB_CABA_Regimen_General_2.5. transaction_dateis interpreted in UTC (UTC+0). Send it in ISO 8601 with the Z suffix and convert from local time before sending. For example, a sale made at 00:10 on July 10, 2026 in Argentina (UTC-3) must be sent as 2026-07-10T03:10:00.000Z.
- The RG 830 concept goes in the item's
Paying out a merchant: SIRTAC + IIBB payment platforms
{
"type": "to settle",
"status": "created",
"currency": "ARS",
"transaction_date": "2026-07-10",
"account_holder_company_id": "5c6e4b83-a032-11ee-a484-0a8bae22163d",
"counterpart": { "company_id": "17d1d461-f707-423d-af8c-cf8cb5aef62a" },
"items": [ { "name": "Liquidación 2026-07-10", "amount": 187468.5, "categories": [{ "code": "out" }] } ]
}Withholdings come back with withholding_type: "WITHHOLDING" and a negative rate and amount. They are subtracted from final_amount, which is the net you transfer:
"taxes": [
{ "name": "Retención IIBB - CABA - Régimen Especial Plataformas de Pago", "rate": -0.025, "amount": -4686.71,
"taxable_amount": 187468.5, "location": "AR-C", "withholding_type": "WITHHOLDING" },
{ "name": "Retención SIRTAC", "rate": -0.03, "amount": -5624.05,
"taxable_amount": 187468.5, "location": "AR-C", "withholding_type": "WITHHOLDING" }
]
Minimum Taxable Amounts: Because the monthly total taxable amount is built from what you sent to Brinta, send every payment to that supplier through/transfers, including the small ones.
Withholdings Brinta determines (examples)
| Regime | Applies when | Rate source |
|---|---|---|
| Ganancias RG 830 | You are an RG 830 agent and the supplier isn't excluded | Concept rate (see the table above) |
| IIBB CABA, Régimen General | You are a CABA withholding agent | Supplier's CABA padrón rate (0.1% to 4.5%) |
| IIBB CABA, Plataformas de Pago | You are a payment platform agent | Fixed by regime |
| SIRTAC | You are a SIRTAC agent | Merchant's SIRTAC rate per jurisdiction; specific rates for "not in padrón" and "no alta" |
| IIBB Córdoba | You are a Córdoba agent | Supplier's Córdoba padrón rate on 80% of the amount |
| IIBB Santa Fe, Corrientes, Tucumán, La Pampa | As configured | Padrón rate or platform regime |
| IVA (RG 3130, security services) | As configured | 8% or 10.5% |
| SUSS | Security and cleaning services | 6% |
| IVA / Ganancias RG 4622 (payment platforms, habitualidad) | Merchant crosses the habituality thresholds | Fixed by regime |
Reference
IVA condition (tax_registrations[].status)
tax_registrations[].status)Responsable inscripto, Responsable monotributo, Exento, No categorizado, No responsable, IVA no alcanzado
Tax ID types
CUIT (business), CUIL, DNI (person). For a provincial IIBB registration: RIIB with level: "state".
Provinces (ISO 3166-2)
| Code | Province | Code | Province | Code | Province |
|---|---|---|---|---|---|
| AR-B | Buenos Aires | AR-L | La Pampa | AR-J | San Juan |
| AR-C | CABA | AR-F | La Rioja | AR-D | San Luis |
| AR-K | Catamarca | AR-M | Mendoza | AR-Z | Santa Cruz |
| AR-H | Chaco | AR-N | Misiones | AR-S | Santa Fe |
| AR-U | Chubut | AR-Q | Neuquén | AR-G | Santiago del Estero |
| AR-X | Córdoba | AR-R | Río Negro | AR-V | Tierra del Fuego |
| AR-W | Corrientes | AR-A | Salta | AR-T | Tucumán |
| AR-E | Entre Ríos | AR-Y | Jujuy | AR-P | Formosa |
Common mistakes
| Mistake | Fix |
|---|---|
Validating with update_company: false and expecting the sale to use the padrón | Only update_company: true on an existing company stores the data. |
| Validating once and never again | Padrón memberships expire monthly. Re-validate each period. |
Sending the counterpart inline (buyer.company) after validating a different company | Reference the validated company with company_id or company_external_id. An inline company is a new company with no padrón data. |
invoice_date or transaction_date outside the validated period | The membership isn't valid on that date, so the out-of-padrón rate may apply. Validate that period with periods. |
state: "CABA" or "Buenos Aires" | Use AR-C and AR-B. |
| Changing the counterpart's company address because one operation happened elsewhere | Send physical_address on that transaction instead. The stored address stays as it is. |
One item per province, but no location entry in its categories | Every item inherits the counterpart's province. Add { "list": "location", "code": "AR-X" } to each item. |
| Expecting a perception or withholding but none appears | Check, in this order: (1) your company is enabled as an agent for that regime; (2) the counterpart's validation succeeded for that month; (3) the jurisdiction; (4) the amount is above the regime minimum. |
| Sending RG 830 payments only when they are large | Send all of them. The monthly accumulation depends on it. |
| Treating withholdings as extra charges | Withholdings are negative and reduce what you pay. Perceptions are positive and increase what the customer pays. |
Updated about 3 hours ago
