> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recurrente.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recurrente.com/_mcp/server.

# Activar facturación electrónica en cuenta conectada

PUT https://app.recurrente.com/api/connected_accounts/{connected_account_id}/tax_invoicing
Content-Type: multipart/form-data

Configura la facturación electrónica administrada por Recurrente para una
cuenta conectada. En v1 `registration_type` debe ser `managed`.

Cuando FEL está listo para emitir se envía `tax_invoice_settings.enabled`.
La respuesta inicial puede indicar que la activación sigue en proceso;
`enabled: true` por sí solo no significa que FEL esté listo.

Después de completar la activación, los checkouts creados con
`X-ACCOUNT-ID` emitirán factura fiscal desde la cuenta conectada.


Reference: https://docs.recurrente.com/referencia-api/api-reference/connected-accounts/update-connected-account-tax-invoicing

## Authentication

- `X-SECRET-KEY` header (required) — Tu clave secreta de API. Una llave de cuenta (`sk_live_...`, `sk_test_...`) opera sobre su propia cuenta y, con `X-ACCOUNT-ID`, sobre sus cuentas conectadas. La llave también fija el ambiente: una `sk_test_` solo lista y resuelve objetos de prueba (`live_mode: false`) y una `sk_live_` solo objetos reales. Un ID del otro ambiente responde `404` (`401` en `/customers`). Una llave de organización (`sk_org_live_...`, `sk_org_test_...`) alcanza todas las cuentas de una organización y solo sirve para leer: saldos, movimientos y reportes. Para operar sobre una cuenta debe nombrarla con `X-ACCOUNT-ID`; omitirlo en una lectura devuelve todas las cuentas de la organización. Cualquier otro endpoint responde `403` con `code: organization_key_unsupported`.

## Request

### Path parameters

- `connected_account_id` (string, required) — ID de la cuenta conectada

### Body (multipart/form-data)

This endpoint expects a multipart form containing an optional file.

- `registration_type` (enum, required) — En v1 solo se permite facturación administrada por Recurrente
- `activation_type` (enum, required) — `automatic` descarga la firma desde SAT usando `sat_password`. `manual` usa el archivo PFX enviado en `firma_electronica`.
- `sat_password` (string, optional) — Requerido cuando `activation_type` es `automatic`
- `firma_electronica` (file, optional) — Archivo PFX requerido cuando `activation_type` es `manual`
- `pfx_password` (string, optional) — Contraseña del PFX requerida cuando `activation_type` es `manual`
- `establishment` (string, optional) — Código de establecimiento. Si se omite, Recurrente usa `1`.

## Response

### 200

Estado actualizado de facturación electrónica

- `provider` (enum, optional, nullable) — Proveedor de facturación fiscal
  - Allowed values: `recurrente`, `custom`
- `registration_type` (enum, optional, nullable) — Tipo de registro de facturación electrónica
  - Allowed values: `managed`, `user_provided`
- `activation_type` (enum, optional, nullable) — Flujo usado para activar facturación electrónica
  - Allowed values: `automatic`, `manual`
- `status` (enum, optional) — Estado público de la activación de facturación electrónica
  - Allowed values: `disabled`, `pending_data`, `ready_to_upload`, `activating`, `pending_fiscal_profile`, `probe_pending`, `activation_attention_required`, `enabled`, `failed`
- `status_notice` (string, optional, nullable) — Mensaje público sobre el estado actual
- `enabled` (boolean, optional) — Indica si la facturación fiscal está habilitada en la cuenta
- `ready_to_invoice` (boolean, optional) — Indica si la cuenta ya tiene credenciales y datos fiscales listos para emitir facturas
- `missing_requirements` (list of string, optional) — Requisitos públicos pendientes antes de poder emitir facturas
- `establishment` (string, optional, nullable) — Código de establecimiento usado para emitir facturas

## Errors

### 400 Bad Request Error

Parámetros incompletos o inválidos

- `message` (string, optional) — Mensaje de error
- `code` (string, optional) — Código estable legible por máquinas, cuando aplica
- `refund_id` (string, optional) — ID del reembolso relacionado cuando aplica
- `endpoint` (string, optional) — Acción de API rechazada, cuando aplica
- `errors` (ErrorErrors, optional) — Detalles de errores por campo

### 404 Not Found Error

Cuenta conectada no encontrada

- `any`

## Types

### ErrorErrors

Detalles de errores por campo

- map from string to ErrorErrorsOneOf0
- list of string
- string

### ErrorErrorsOneOf0

- list of string
- string

## Examples

### Activación manual con PFX

**Request**

```json
{
  "registration_type": "managed",
  "activation_type": "manual",
  "firma_electronica": "<file: (archivo .pfx)>",
  "pfx_password": "pfx-password",
  "establishment": "1"
}
```

**Response**

```json
{
  "provider": "recurrente",
  "registration_type": "managed",
  "activation_type": "automatic",
  "status": "ready_to_upload",
  "status_notice": "Estamos activando tu facturación. Te notificaremos cuando esté lista.",
  "enabled": true,
  "ready_to_invoice": false,
  "missing_requirements": [
    "API keys",
    "establishments",
    "tax phrases"
  ],
  "establishment": "1"
}
```

**SDK Code**

```python Activación manual con PFX
import requests

url = "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing"

files = { "firma_electronica": "open('(archivo .pfx)', 'rb')" }
payload = {
    "registration_type": "managed",
    "activation_type": "manual",
    "sat_password": ,
    "pfx_password": "pfx-password",
    "establishment": "1"
}
headers = {"X-SECRET-KEY": "<apiKey>"}

response = requests.put(url, data=payload, files=files, headers=headers)

print(response.json())
```

```javascript Activación manual con PFX
const url = 'https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing';
const form = new FormData();
form.append('registration_type', 'managed');
form.append('activation_type', 'manual');
form.append('sat_password', '');
form.append('firma_electronica', '(archivo .pfx)');
form.append('pfx_password', 'pfx-password');
form.append('establishment', '1');

const options = {method: 'PUT', headers: {'X-SECRET-KEY': '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Activación manual con PFX
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nmanual\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"(archivo .pfx)\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\npfx-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("X-SECRET-KEY", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Activación manual con PFX
require 'uri'
require 'net/http'

url = URI("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["X-SECRET-KEY"] = '<apiKey>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nmanual\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"(archivo .pfx)\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\npfx-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java Activación manual con PFX
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")
  .header("X-SECRET-KEY", "<apiKey>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nmanual\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"(archivo .pfx)\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\npfx-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php Activación manual con PFX
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing', [
  'multipart' => [
    [
        'name' => 'registration_type',
        'contents' => 'managed'
    ],
    [
        'name' => 'activation_type',
        'contents' => 'manual'
    ],
    [
        'name' => 'firma_electronica',
        'filename' => '(archivo .pfx)',
        'contents' => null
    ],
    [
        'name' => 'pfx_password',
        'contents' => 'pfx-password'
    ],
    [
        'name' => 'establishment',
        'contents' => '1'
    ]
  ]
  'headers' => [
    'X-SECRET-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Activación manual con PFX
using RestSharp;

var client = new RestClient("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing");
var request = new RestRequest(Method.PUT);
request.AddHeader("X-SECRET-KEY", "<apiKey>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nmanual\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"(archivo .pfx)\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\npfx-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Activación manual con PFX
import Foundation

let headers = ["X-SECRET-KEY": "<apiKey>"]
let parameters = [
  [
    "name": "registration_type",
    "value": "managed"
  ],
  [
    "name": "activation_type",
    "value": "manual"
  ],
  [
    "name": "sat_password",
    "value": 
  ],
  [
    "name": "firma_electronica",
    "fileName": "(archivo .pfx)"
  ],
  [
    "name": "pfx_password",
    "value": "pfx-password"
  ],
  [
    "name": "establishment",
    "value": "1"
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Example 2

**Request**

```json
{
  "registration_type": "managed",
  "activation_type": "automatic",
  "sat_password": "sat-password",
  "firma_electronica": "<file: <file1>>",
  "establishment": "1"
}
```

**Response**

```json
{
  "provider": "recurrente",
  "registration_type": "managed",
  "activation_type": "automatic",
  "status": "ready_to_upload",
  "status_notice": "Estamos activando tu facturación. Te notificaremos cuando esté lista.",
  "enabled": true,
  "ready_to_invoice": false,
  "missing_requirements": [
    "API keys",
    "establishments",
    "tax phrases"
  ],
  "establishment": "1"
}
```

**SDK Code**

```python
import requests

url = "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing"

files = { "firma_electronica": "open('<file1>', 'rb')" }
payload = {
    "registration_type": "managed",
    "activation_type": "automatic",
    "sat_password": "sat-password",
    "pfx_password": ,
    "establishment": "1"
}
headers = {"X-SECRET-KEY": "<apiKey>"}

response = requests.put(url, data=payload, files=files, headers=headers)

print(response.json())
```

```javascript
const url = 'https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing';
const form = new FormData();
form.append('registration_type', 'managed');
form.append('activation_type', 'automatic');
form.append('sat_password', 'sat-password');
form.append('firma_electronica', '<file1>');
form.append('pfx_password', '');
form.append('establishment', '1');

const options = {method: 'PUT', headers: {'X-SECRET-KEY': '<apiKey>'}};

options.body = form;

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing"

	payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nautomatic\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\nsat-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("X-SECRET-KEY", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["X-SECRET-KEY"] = '<apiKey>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nautomatic\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\nsat-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")
  .header("X-SECRET-KEY", "<apiKey>")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nautomatic\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\nsat-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing', [
  'multipart' => [
    [
        'name' => 'registration_type',
        'contents' => 'managed'
    ],
    [
        'name' => 'activation_type',
        'contents' => 'automatic'
    ],
    [
        'name' => 'sat_password',
        'contents' => 'sat-password'
    ],
    [
        'name' => 'firma_electronica',
        'filename' => '<file1>',
        'contents' => null
    ],
    [
        'name' => 'establishment',
        'contents' => '1'
    ]
  ]
  'headers' => [
    'X-SECRET-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing");
var request = new RestRequest(Method.PUT);
request.AddHeader("X-SECRET-KEY", "<apiKey>");
request.AddParameter("undefined", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"registration_type\"\r\n\r\nmanaged\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"activation_type\"\r\n\r\nautomatic\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"sat_password\"\r\n\r\nsat-password\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"firma_electronica\"; filename=\"<file1>\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"pfx_password\"\r\n\r\n\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"establishment\"\r\n\r\n1\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["X-SECRET-KEY": "<apiKey>"]
let parameters = [
  [
    "name": "registration_type",
    "value": "managed"
  ],
  [
    "name": "activation_type",
    "value": "automatic"
  ],
  [
    "name": "sat_password",
    "value": "sat-password"
  ],
  [
    "name": "firma_electronica",
    "fileName": "<file1>"
  ],
  [
    "name": "pfx_password",
    "value": 
  ],
  [
    "name": "establishment",
    "value": "1"
  ]
]

let boundary = "---011000010111000001101001"

var body = ""
var error: NSError? = nil
for param in parameters {
  let paramName = param["name"]!
  body += "--\(boundary)\r\n"
  body += "Content-Disposition:form-data; name=\"\(paramName)\""
  if let filename = param["fileName"] {
    let contentType = param["content-type"]!
    let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
    if (error != nil) {
      print(error as Any)
    }
    body += "; filename=\"\(filename)\"\r\n"
    body += "Content-Type: \(contentType)\r\n\r\n"
    body += fileContent
  } else if let paramValue = param["value"] {
    body += "\r\n\r\n\(paramValue)"
  }
}

let request = NSMutableURLRequest(url: NSURL(string: "https://app.recurrente.com/api/connected_accounts/connected_account_id/tax_invoicing")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```