Introduction
API RESTful para gestión de contribuyentes, categorías, documentos emitidos, documentos recibidos y reportes tributarios.
Esta documentación proporciona toda la información necesaria para trabajar con la API de Taxo Impuestos.
## Ambientes
La API está disponible en los siguientes ambientes:
| Ambiente | URL | Descripción |
|----------|-----|-------------|
| **Staging** | `https://ec-demo.taxo.co` | Ambiente de pruebas y desarrollo |
| **Producción** | `https://ec-impuestos.taxo.co` | Ambiente productivo *(próximamente)* |
<aside class="warning">⚠️ Actualmente esta documentación apunta al ambiente de <strong>Staging</strong>. Los ejemplos de código usan la URL de staging.</aside>
## Autenticación
Todas las peticiones a la API requieren dos headers:
- **x-api-key**: Tu API key proporcionado por TWS
- **x-organization-id**: Tu organization ID de TWS
## Rate Limiting
La API está limitada a 60 peticiones por minuto por API key.
<aside>A medida que navegues por la documentación, verás ejemplos de código en diferentes lenguajes en el área oscura a la derecha.</aside>
Authenticating requests
To authenticate requests, include a x-api-key header with the value "YOUR_API_KEY_HERE".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Puedes obtener tu API key y Organization ID desde tu dashboard de TWS.
Debes incluir también el header x-organization-id con tu Organization ID.
Taxpayers
API endpoints for managing taxpayers and their related data.
List taxpayers
requires authentication
Retrieves a paginated list of all taxpayers belonging to the authenticated organization. You can filter and sort the results using query parameters.
Example request:
curl --request GET \
--get "https://ec-demo.taxo.co/api/v1/taxpayers?page=1&per_page=20&sort=-created_at&search=Empresa+S.A.&status=1&iva_period=MENSUAL&tax_regime_cat=GENERAL&declaration_day=10" \
--header "x-api-key: YOUR_API_KEY_HERE" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "x-organization-id: {YOUR_ORGANIZATION_ID}"const url = new URL(
"https://ec-demo.taxo.co/api/v1/taxpayers"
);
const params = {
"page": "1",
"per_page": "20",
"sort": "-created_at",
"search": "Empresa S.A.",
"status": "1",
"iva_period": "MENSUAL",
"tax_regime_cat": "GENERAL",
"declaration_day": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"x-api-key": "YOUR_API_KEY_HERE",
"Content-Type": "application/json",
"Accept": "application/json",
"x-organization-id": "{YOUR_ORGANIZATION_ID}",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://ec-demo.taxo.co/api/v1/taxpayers';
$response = $client->get(
$url,
[
'headers' => [
'x-api-key' => 'YOUR_API_KEY_HERE',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-organization-id' => '{YOUR_ORGANIZATION_ID}',
],
'query' => [
'page' => '1',
'per_page' => '20',
'sort' => '-created_at',
'search' => 'Empresa S.A.',
'status' => '1',
'iva_period' => 'MENSUAL',
'tax_regime_cat' => 'GENERAL',
'declaration_day' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://ec-demo.taxo.co/api/v1/taxpayers'
params = {
'page': '1',
'per_page': '20',
'sort': '-created_at',
'search': 'Empresa S.A.',
'status': '1',
'iva_period': 'MENSUAL',
'tax_regime_cat': 'GENERAL',
'declaration_day': '10',
}
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-organization-id': '{YOUR_ORGANIZATION_ID}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200, Success):
{
"status": "success",
"message": "Taxpayers retrieved successfully",
"data": {
"taxpayers": [
{
"id": 144,
"ulid": "01HZXXX...",
"tax_number": "1726051285001",
"business_name": "EMPRESA DEMO S.A.",
"trade_name": "DEMO",
"tax_payer_status": "ACTIVE",
"tax_regime": "general",
"tax_regime_cat": "general",
"iva_period": "monthly",
"declaration_day": 12,
"required_to_keep_accounts": "SI",
"withholding_agent": "SI",
"special_contributor": "NO",
"economic_activity": "Actividades de consultoría de gestión empresarial",
"start_activities_date": "2020-01-15T00:00:00.000000Z",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
]
},
"meta": {
"pagination": {
"total": 5,
"count": 5,
"per_page": 20,
"current_page": 1,
"total_pages": 1
},
"filters": {
"status": "ACTIVE"
}
}
}
Example response (401, Unauthorized):
{
"status": "error",
"message": "Invalid API key or organization ID",
"code": "UNAUTHORIZED"
}
Example response (500, Server error):
{
"status": "error",
"message": "An error occurred while retrieving taxpayers",
"code": "SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a new taxpayer
requires authentication
Creates a new taxpayer in your organization after validating that the tax identifier exists in the TWS (Tax Web Services) registry. Accepts RUC (13 digits), Cédula (10 digits), or Passport.
This endpoint will:
- Validate the taxpayer doesn't already exist in your organization
- Query the TWS registry API to verify the identifier is valid and active
- Create the taxpayer with all available data from TWS
- Automatically create default categories for document classification
- Set up auto-categorization rules
Note: This process may take 5-10 seconds as it queries external services.
Example request:
curl --request POST \
"https://ec-demo.taxo.co/api/v1/taxpayers" \
--header "x-api-key: YOUR_API_KEY_HERE" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "x-organization-id: {YOUR_ORGANIZATION_ID}" \
--data "{
\"taxpayerId\": \"1726051285001\"
}"
const url = new URL(
"https://ec-demo.taxo.co/api/v1/taxpayers"
);
const headers = {
"x-api-key": "YOUR_API_KEY_HERE",
"Content-Type": "application/json",
"Accept": "application/json",
"x-organization-id": "{YOUR_ORGANIZATION_ID}",
};
let body = {
"taxpayerId": "1726051285001"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://ec-demo.taxo.co/api/v1/taxpayers';
$response = $client->post(
$url,
[
'headers' => [
'x-api-key' => 'YOUR_API_KEY_HERE',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-organization-id' => '{YOUR_ORGANIZATION_ID}',
],
'json' => [
'taxpayerId' => '1726051285001',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://ec-demo.taxo.co/api/v1/taxpayers'
payload = {
"taxpayerId": "1726051285001"
}
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-organization-id': '{YOUR_ORGANIZATION_ID}'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (201, Taxpayer created successfully):
{
"status": "success",
"message": "Taxpayer created successfully",
"data": {
"taxpayer": {
"id": "01JDXYZ123ABC456DEF789GHI",
"tax_number": "1726051285001",
"business_name": "AGUIRRE MEJIA AIDA ISABEL",
"legal_name": "AGUIRRE MEJIA AIDA ISABEL",
"email": null,
"phone": null,
"status": 1,
"tax_payer_status": "ACTIVO",
"economic_activity": "VENTA AL POR MAYOR DE FRUTAS",
"tax_regime": "GENERAL",
"tax_regime_cat": "general",
"iva_period": "monthly",
"category": null,
"required_to_keep_accounts": "NO",
"withholding_agent": "NO",
"special_contributor": "NO",
"declaration_day": 12,
"next_declaration": null,
"start_activities_date": "2018-09-04",
"last_sync_at": null,
"created_at": "2024-12-02 15:30:45",
"updated_at": "2024-12-02 15:30:45"
}
}
}
Example response (401, Unauthorized):
{
"status": "error",
"message": "Invalid API key or organization ID",
"code": "UNAUTHORIZED"
}
Example response (404, Taxpayer not found in TWS):
{
"status": "error",
"message": "Taxpayer not found in TWS. Please verify the taxpayer ID",
"code": "TAXPAYER_NOT_FOUND_IN_TWS"
}
Example response (409, Taxpayer already exists):
{
"status": "error",
"message": "Taxpayer already exists for this organization",
"code": "TAXPAYER_ALREADY_EXISTS"
}
Example response (422, Validation error):
{
"status": "error",
"message": "Validation failed",
"code": "VALIDATION_ERROR",
"errors": {
"taxpayerId": [
"The taxpayer ID can only contain letters, numbers, and hyphens"
]
}
}
Example response (500, Internal server error):
{
"status": "error",
"message": "Failed to create taxpayer due to an internal error",
"code": "INTERNAL_SERVER_ERROR"
}
Example response (503, TWS service unavailable):
{
"status": "error",
"message": "Unable to verify taxpayer with TWS app",
"code": "TWS_SERVICE_UNAVAILABLE"
}
Example response (504, TWS service timeout):
{
"status": "error",
"message": "TWS service timeout. Please try again later",
"code": "TWS_SERVICE_TIMEOUT"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a specific taxpayer
requires authentication
Retrieves detailed information for a specific taxpayer identified by their RUC number. The taxpayer must belong to the authenticated organization.
Example request:
curl --request GET \
--get "https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001" \
--header "x-api-key: YOUR_API_KEY_HERE" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "x-organization-id: {YOUR_ORGANIZATION_ID}"const url = new URL(
"https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001"
);
const headers = {
"x-api-key": "YOUR_API_KEY_HERE",
"Content-Type": "application/json",
"Accept": "application/json",
"x-organization-id": "{YOUR_ORGANIZATION_ID}",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001';
$response = $client->get(
$url,
[
'headers' => [
'x-api-key' => 'YOUR_API_KEY_HERE',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-organization-id' => '{YOUR_ORGANIZATION_ID}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001'
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-organization-id': '{YOUR_ORGANIZATION_ID}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200, Success):
{
"status": "success",
"message": "Taxpayer retrieved successfully",
"data": {
"taxpayer": {
"id": 144,
"ulid": "01HZXXX...",
"tax_number": "1726051285001",
"business_name": "EMPRESA DEMO S.A.",
"trade_name": "DEMO",
"address": "Av. Principal 123 y Secundaria",
"phone": "0987654321",
"email": "contacto@demo.com",
"legal_representatives": "Juan Pérez, María González",
"economic_activity": "Actividades de consultoría de gestión empresarial",
"tax_payer_status": "ACTIVE",
"tax_payer_type": "PERSONA JURÍDICA",
"tax_regime": "general",
"tax_regime_cat": "general",
"category": null,
"iva_period": "monthly",
"declaration_day": 12,
"required_to_keep_accounts": "SI",
"withholding_agent": "SI",
"special_contributor": "NO",
"ghost_taxpayer": "NO",
"nonexistent_transactions": "NO",
"start_activities_date": "2020-01-15T00:00:00.000000Z",
"cessation_date": null,
"restart_activities_date": null,
"information_update_date": "2024-01-15T00:00:00.000000Z",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
}
}
Example response (401, Unauthorized):
{
"status": "error",
"message": "Invalid API key or organization ID",
"code": "UNAUTHORIZED"
}
Example response (404, Taxpayer not found):
{
"status": "error",
"message": "Taxpayer not found",
"code": "TAXPAYER_NOT_FOUND"
}
Example response (500, Server error):
{
"status": "error",
"message": "An error occurred while retrieving the taxpayer",
"code": "SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get taxpayer categories
requires authentication
Retrieves a paginated list of categories for a specific taxpayer. Categories are used to classify purchase and sales documents.
Example request:
curl --request GET \
--get "https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001/categories?page=1&per_page=20&document_type=sales&category_type=commercial_expenses&enabled=1&editable=1&search=Alimentaci%C3%B3n&filter[document_type]=purchases&filter[category_type]=personal_expenses&filter[search]=vmqeopfuudtdsufvyvddq" \
--header "x-api-key: YOUR_API_KEY_HERE" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--header "x-organization-id: {YOUR_ORGANIZATION_ID}"const url = new URL(
"https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001/categories"
);
const params = {
"page": "1",
"per_page": "20",
"document_type": "sales",
"category_type": "commercial_expenses",
"enabled": "1",
"editable": "1",
"search": "Alimentación",
"filter[document_type]": "purchases",
"filter[category_type]": "personal_expenses",
"filter[search]": "vmqeopfuudtdsufvyvddq",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"x-api-key": "YOUR_API_KEY_HERE",
"Content-Type": "application/json",
"Accept": "application/json",
"x-organization-id": "{YOUR_ORGANIZATION_ID}",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001/categories';
$response = $client->get(
$url,
[
'headers' => [
'x-api-key' => 'YOUR_API_KEY_HERE',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'x-organization-id' => '{YOUR_ORGANIZATION_ID}',
],
'query' => [
'page' => '1',
'per_page' => '20',
'document_type' => 'sales',
'category_type' => 'commercial_expenses',
'enabled' => '1',
'editable' => '1',
'search' => 'Alimentación',
'filter[document_type]' => 'purchases',
'filter[category_type]' => 'personal_expenses',
'filter[search]' => 'vmqeopfuudtdsufvyvddq',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://ec-demo.taxo.co/api/v1/taxpayers/1726051285001/categories'
params = {
'page': '1',
'per_page': '20',
'document_type': 'sales',
'category_type': 'commercial_expenses',
'enabled': '1',
'editable': '1',
'search': 'Alimentación',
'filter[document_type]': 'purchases',
'filter[category_type]': 'personal_expenses',
'filter[search]': 'vmqeopfuudtdsufvyvddq',
}
headers = {
'x-api-key': 'YOUR_API_KEY_HERE',
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-organization-id': '{YOUR_ORGANIZATION_ID}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200, Success):
{
"status": "success",
"message": "Categories retrieved successfully",
"data": {
"categories": [
{
"id": 9857,
"name": "Alimentación",
"code": "D-001",
"description": null,
"icon": "M20 10a5.27...",
"color": "bg-teal-500",
"document_type": "purchases",
"category_type": "personal_expenses",
"editable": false,
"has_been_edited": false,
"enabled": true,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z",
"archived_at": null
}
]
},
"meta": {
"pagination": {
"total": 30,
"count": 20,
"per_page": 20,
"current_page": 1,
"total_pages": 2
},
"filters": {
"document_type": "purchases",
"enabled": true
}
}
}
Example response (401, Unauthorized):
{
"status": "error",
"message": "Invalid API key or organization ID",
"code": "UNAUTHORIZED"
}
Example response (404, Taxpayer not found):
{
"status": "error",
"message": "Taxpayer not found or access denied",
"code": "TAXPAYER_NOT_FOUND"
}
Example response (500, Server error):
{
"status": "error",
"message": "Failed to retrieve categories. Please try again later.",
"code": "SERVER_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.