[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:

  1. Validate the counterpart's CUIT with /tax-id-validations. Brinta stores their tax condition and padrón rates.
  2. Send the operation:
    • /sales for perceptions;
    • /transfers for withholdings.
  3. Brinta applies the right taxes, rates, bases and minimums.

You never send rates or padrón data yourself.

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

InputWhere 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.
JurisdictionCounterpart 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 conceptItem categories, for example an activity code on sales or the RG 830 concept on payments.
Dateinvoice_date on sales, transaction_date on transfers. Padrón memberships are applied only if valid on that date.
MinimumsConfigured 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"]
  }'
FieldNotes
company_id / company_external_idThe company to validate. Results are written to it only when update_company is true.
update_companytrue 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.
periodsOptional, ["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

Each entry is one padrón the CUIT belongs to, for one period.

Name patternMeaning
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-XRegistered 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>_ExentoExclusions and exemptions. While valid, the matching tax is not applied.
percep_IVA_ARCAIVA perception classification from ARCA.
  • The rate in the name is a percentage (2.5 = 2.5%). The rate field is the same value as a fraction (0.025).
  • An empty registry_lists means 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 after valid_until no longer sees the rate. Schedule a validation for each active counterpart when the new padrones come out. Use periods: ["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": true inside buyer (on /sales) or counterpart (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:

SituationUse
The whole operation happens in a single province that differs from the counterpart's addressphysical_address on buyer (sales) or counterpart (transfers)
Items in the same transaction belong to different provincesA 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

Example: 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_address sits next to company_id, company_external_id or company, and works with any of them.
  • country is 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 as counterpart.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

Example: 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 location entry 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 /transfers items. 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_id is you, the seller. Your agent registrations decide which regimes are even considered.
  • buyer.company_id is the validated customer. Their IVA condition and padrón rates are read from the company.
  • invoice_date picks the padrón period. Send the date of the invoice.
  • invoice_date is 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 location category 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)

RegimeApplies whenRate source
Percepción IVA (general regime)You are an IVA perception agent and the buyer is Responsable inscripto3%
Percepción IVA, No categorizadoBuyer is No categorizado10.5% on the amount plus IVA
Percepción IIBB Buenos Aires (ARBA)You are an ARBA agentBuyer'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 agentBuyer'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 agentBuyer's Santa Fe padrón rate; 0% if excluded; 6% if not in the padrón
Percepción IIBB TucumánYou are a Tucumán agentTucumá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órdobaAs configured per provincePadrón rate, Convenio Multilateral or local status
Digital services regimes: AGIP RG 312/2019, ARBA RG 38/2019, Córdoba, Santa Fe and othersCross-border digital servicesFixed rates (for example 2%)
Municipal: La Plata TISH, Córdoba RG 18, PosadasAs configuredFixed rates

Step 4b: Payments with withholdings

Use /transfers:

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 list rg_830. Code 94 is 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_date is 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.

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)

RegimeApplies whenRate source
Ganancias RG 830You are an RG 830 agent and the supplier isn't excludedConcept rate (see the table above)
IIBB CABA, Régimen GeneralYou are a CABA withholding agentSupplier's CABA padrón rate (0.1% to 4.5%)
IIBB CABA, Plataformas de PagoYou are a payment platform agentFixed by regime
SIRTACYou are a SIRTAC agentMerchant's SIRTAC rate per jurisdiction; specific rates for "not in padrón" and "no alta"
IIBB CórdobaYou are a Córdoba agentSupplier's Córdoba padrón rate on 80% of the amount
IIBB Santa Fe, Corrientes, Tucumán, La PampaAs configuredPadrón rate or platform regime
IVA (RG 3130, security services)As configured8% or 10.5%
SUSSSecurity and cleaning services6%
IVA / Ganancias RG 4622 (payment platforms, habitualidad)Merchant crosses the habituality thresholdsFixed by regime

Reference

IVA condition (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)

CodeProvinceCodeProvinceCodeProvince
AR-BBuenos AiresAR-LLa PampaAR-JSan Juan
AR-CCABAAR-FLa RiojaAR-DSan Luis
AR-KCatamarcaAR-MMendozaAR-ZSanta Cruz
AR-HChacoAR-NMisionesAR-SSanta Fe
AR-UChubutAR-QNeuquénAR-GSantiago del Estero
AR-XCórdobaAR-RRío NegroAR-VTierra del Fuego
AR-WCorrientesAR-ASaltaAR-TTucumán
AR-EEntre RíosAR-YJujuyAR-PFormosa

Common mistakes

MistakeFix
Validating with update_company: false and expecting the sale to use the padrónOnly update_company: true on an existing company stores the data.
Validating once and never againPadrón memberships expire monthly. Re-validate each period.
Sending the counterpart inline (buyer.company) after validating a different companyReference 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 periodThe 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 elsewhereSend physical_address on that transaction instead. The stored address stays as it is.
One item per province, but no location entry in its categoriesEvery item inherits the counterpart's province. Add { "list": "location", "code": "AR-X" } to each item.
Expecting a perception or withholding but none appearsCheck, 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 largeSend all of them. The monthly accumulation depends on it.
Treating withholdings as extra chargesWithholdings are negative and reduce what you pay. Perceptions are positive and increase what the customer pays.

Did this page help you?