Introduction
The RespondeIA API allows you to integrate AI-powered customer service automation into any platform, application, or workflow. Built on REST principles, it uses standard HTTP methods and returns JSON-formatted responses.
Base URL
All API requests are made to:
https://api.respondeia.com/v1
Always use HTTPS. HTTP requests will be rejected.
Authentication
RespondeIA uses Bearer token authentication. Include your API token in the Authorization header:
Authorization: Bearer YOUR_API_TOKEN
Obtaining API Tokens
Based on the authentication pattern in /home/daytona/workspace/source/modules/auth/services/auth.service.ts:1-18:
interface LoginResponse {
user : {
user : any ;
token : string ;
};
}
async function login ( email : string , password : string ) : Promise < string > {
const response = await fetch ( 'https://api.respondeia.com/v1/auth/login' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
email ,
password
})
});
if ( ! response . ok ) {
throw new Error ( 'Credenciales incorrectas' );
}
const data : LoginResponse = await response . json ();
return data . user . token ;
}
Creating API Keys
For programmatic access, generate long-lived API keys:
async function createApiKey ( name : string , permissions : string []) {
const response = await fetch ( 'https://api.respondeia.com/v1/auth/api-keys' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ token } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
name ,
permissions
})
});
const { apiKey , createdAt } = await response . json ();
return apiKey ;
}
// Example: Create key with full access
const apiKey = await createApiKey ( 'Production API' , [
'messages:read' ,
'messages:write' ,
'customers:read' ,
'customers:write' ,
'analytics:read' ,
'webhooks:manage'
]);
Store API keys securely. They provide full access to your account. Never commit them to version control.
Rate Limiting
API requests are rate-limited based on your plan:
Plan Rate Limit Burst Limit Básico 100 req/min 150 req/min Pro 500 req/min 750 req/min Agencia 2000 req/min 3000 req/min Enterprise Custom Custom
Every response includes rate limit information:
X-RateLimit-Limit : 500
X-RateLimit-Remaining : 487
X-RateLimit-Reset : 1678886400
Handling Rate Limits
interface RateLimitError {
error : 'rate_limit_exceeded' ;
retryAfter : number ;
}
async function apiRequestWithRetry ( url : string , options : RequestInit ) {
const response = await fetch ( url , options );
if ( response . status === 429 ) {
const retryAfter = parseInt ( response . headers . get ( 'Retry-After' ) || '60' );
console . log ( `Rate limited. Retrying after ${ retryAfter } s` );
await new Promise ( resolve => setTimeout ( resolve , retryAfter * 1000 ));
return apiRequestWithRetry ( url , options );
}
return response ;
}
Error Handling
The API uses standard HTTP status codes and returns structured error responses:
Status Codes
Code Description 200 Success 201 Created 400 Bad Request - Invalid parameters 401 Unauthorized - Invalid or missing token 403 Forbidden - Insufficient permissions 404 Not Found - Resource doesn’t exist 429 Too Many Requests - Rate limit exceeded 500 Internal Server Error 503 Service Unavailable - Temporary outage
{
"error" : {
"code" : "invalid_parameter" ,
"message" : "The 'customer_id' parameter is required" ,
"field" : "customer_id" ,
"documentation_url" : "https://docs.respondeia.com/api/errors#invalid_parameter"
}
}
Error Handling Example
async function handleApiRequest < T >( url : string , options : RequestInit ) : Promise < T > {
const response = await fetch ( url , options );
if ( ! response . ok ) {
const error = await response . json ();
switch ( response . status ) {
case 400 :
throw new Error ( `Bad Request: ${ error . error . message } ` );
case 401 :
throw new Error ( 'Unauthorized: Invalid API token' );
case 403 :
throw new Error ( 'Forbidden: Insufficient permissions' );
case 404 :
throw new Error ( 'Not Found: Resource does not exist' );
case 429 :
throw new Error ( 'Rate limit exceeded' );
case 500 :
throw new Error ( 'Internal server error' );
default :
throw new Error ( `API Error: ${ error . error . message } ` );
}
}
return response . json ();
}
Core Endpoints
Messages
Send and receive messages across channels (WhatsApp, etc.):
// Send a message
POST / v1 / messages / send
// Get message history
GET / v1 / messages ? customer_id = { id } & limit = 50
// Get single message
GET / v1 / messages / { message_id }
// Mark message as read
POST / v1 / messages / { message_id } / read
Customers
Manage customer profiles and conversation history:
// List customers
GET / v1 / customers ? page = 1 & limit = 100
// Get customer details
GET / v1 / customers / { customer_id }
// Update customer
PATCH / v1 / customers / { customer_id }
// Get customer conversations
GET / v1 / customers / { customer_id } / conversations
AI Training
Train and configure your AI assistant:
// Upload training data
POST / v1 / ai / training / upload
// Get training status
GET / v1 / ai / training / status
// Update AI settings
PATCH / v1 / ai / settings
// Test AI response
POST / v1 / ai / test
Payments
Manage payments and transactions:
// Create payment
POST / v1 / payments / create
// Get payment status
GET / v1 / payments / { payment_id }
// Refund payment
POST / v1 / payments / { payment_id } / refund
// List transactions
GET / v1 / payments ? start_date = { date } & end_date = { date }
Analytics
Retrieve performance metrics:
// Get dashboard metrics
GET / v1 / analytics / dashboard
// Get conversation metrics
GET / v1 / analytics / conversations ? period = 7 d
// Get AI performance
GET / v1 / analytics / ai - performance
// Export data
POST / v1 / analytics / export
Webhooks
Manage webhook subscriptions:
// Create webhook
POST / v1 / webhooks
// List webhooks
GET / v1 / webhooks
// Delete webhook
DELETE / v1 / webhooks / { webhook_id }
// Test webhook
POST / v1 / webhooks / { webhook_id } / test
Detailed Examples
Send a WhatsApp Message
interface SendMessageParams {
channel : 'whatsapp' | 'telegram' | 'webchat' ;
to : string ;
content : string ;
type : 'text' | 'image' | 'document' | 'location' ;
mediaUrl ?: string ;
}
async function sendMessage ( params : SendMessageParams ) {
const response = await fetch ( 'https://api.respondeia.com/v1/messages/send' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( params )
});
if ( ! response . ok ) {
throw new Error ( 'Failed to send message' );
}
const { messageId , status , sentAt } = await response . json ();
return { messageId , status , sentAt };
}
// Example: Send text message
const result = await sendMessage ({
channel: 'whatsapp' ,
to: 'wa:5491123456789' ,
content: 'Hola! Cómo puedo ayudarte hoy?' ,
type: 'text'
});
console . log ( `Message sent: ${ result . messageId } ` );
Retrieve Conversation History
interface Message {
id : string ;
customerId : string ;
content : string ;
type : 'text' | 'image' | 'document' ;
direction : 'inbound' | 'outbound' ;
timestamp : number ;
status : 'sent' | 'delivered' | 'read' | 'failed' ;
aiGenerated : boolean ;
}
interface ConversationResponse {
messages : Message [];
totalCount : number ;
hasMore : boolean ;
nextCursor ?: string ;
}
async function getConversation (
customerId : string ,
limit : number = 50 ,
cursor ?: string
) : Promise < ConversationResponse > {
const params = new URLSearchParams ({
customer_id: customerId ,
limit: limit . toString (),
... ( cursor && { cursor })
});
const response = await fetch (
`https://api.respondeia.com/v1/messages? ${ params } ` ,
{
headers: {
'Authorization' : `Bearer ${ apiKey } `
}
}
);
if ( ! response . ok ) {
throw new Error ( 'Failed to fetch conversation' );
}
return response . json ();
}
// Example: Get last 50 messages
const conversation = await getConversation ( 'wa:5491123456789' , 50 );
conversation . messages . forEach ( msg => {
const source = msg . aiGenerated ? '[AI]' : '[Human]' ;
const direction = msg . direction === 'inbound' ? '←' : '→' ;
console . log ( ` ${ source } ${ direction } ${ msg . content } ` );
});
if ( conversation . hasMore ) {
// Fetch next page
const nextPage = await getConversation (
'wa:5491123456789' ,
50 ,
conversation . nextCursor
);
}
Create and Track Payment
interface Payment {
id : string ;
customerId : string ;
amount : number ;
currency : string ;
status : 'pending' | 'approved' | 'rejected' | 'refunded' ;
paymentLink : string ;
createdAt : number ;
paidAt ?: number ;
}
async function createPayment (
customerId : string ,
amount : number ,
description : string
) : Promise < Payment > {
const response = await fetch ( 'https://api.respondeia.com/v1/payments/create' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
provider: 'mercadopago' ,
customer_id: customerId ,
amount: amount ,
currency: 'ARS' ,
description: description ,
notification_url: `https://api.respondeia.com/webhooks/mercadopago/ ${ accountId } ` ,
auto_return: 'approved'
})
});
if ( ! response . ok ) {
throw new Error ( 'Failed to create payment' );
}
return response . json ();
}
async function pollPaymentStatus (
paymentId : string ,
maxAttempts : number = 60
) : Promise < Payment > {
for ( let i = 0 ; i < maxAttempts ; i ++ ) {
const response = await fetch (
`https://api.respondeia.com/v1/payments/ ${ paymentId } ` ,
{
headers: {
'Authorization' : `Bearer ${ apiKey } `
}
}
);
const payment : Payment = await response . json ();
if ( payment . status === 'approved' ) {
return payment ;
}
if ( payment . status === 'rejected' ) {
throw new Error ( 'Payment rejected' );
}
// Wait 5 seconds before next check
await new Promise ( resolve => setTimeout ( resolve , 5000 ));
}
throw new Error ( 'Payment timeout' );
}
// Example usage
const payment = await createPayment (
'wa:5491123456789' ,
5900 , // $59.00
'Plan Pro - Mensual'
);
// Send payment link via WhatsApp
await sendMessage ({
channel: 'whatsapp' ,
to: 'wa:5491123456789' ,
content: `Tu enlace de pago: ${ payment . paymentLink } ` ,
type: 'text'
});
// Poll for payment completion
try {
const completedPayment = await pollPaymentStatus ( payment . id );
console . log ( `Payment approved at ${ new Date ( completedPayment . paidAt ! ) } ` );
// Send confirmation
await sendMessage ({
channel: 'whatsapp' ,
to: 'wa:5491123456789' ,
content: 'Pago confirmado! Gracias por tu compra.' ,
type: 'text'
});
} catch ( error ) {
console . error ( 'Payment failed:' , error );
}
Upload AI Training Data
interface TrainingData {
type : 'faq' | 'product_catalog' | 'business_info' | 'conversation_examples' ;
data : any ;
}
async function uploadTrainingData ( training : TrainingData ) {
const response = await fetch ( 'https://api.respondeia.com/v1/ai/training/upload' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( training )
});
if ( ! response . ok ) {
throw new Error ( 'Failed to upload training data' );
}
const { jobId , status } = await response . json ();
return { jobId , status };
}
// Example: Upload FAQ data
const faqData = {
type: 'faq' as const ,
data: {
faqs: [
{
question: "Cuáles son los horarios de atención?" ,
answer: "Nuestro AI está disponible 24/7. Atención humana de 9 AM a 6 PM de lunes a viernes."
},
{
question: "Cómo cancelo mi suscripción?" ,
answer: "Puedes cancelar en cualquier momento desde tu panel de control en Configuración → Suscripción."
},
{
question: "Ofrecen prueba gratuita?" ,
answer: "Sí! Ofrecemos 7 días gratis sin necesidad de tarjeta de crédito."
}
]
}
};
const job = await uploadTrainingData ( faqData );
console . log ( `Training job started: ${ job . jobId } ` );
// Check training status
async function checkTrainingStatus ( jobId : string ) {
const response = await fetch (
`https://api.respondeia.com/v1/ai/training/status?job_id= ${ jobId } ` ,
{
headers: {
'Authorization' : `Bearer ${ apiKey } `
}
}
);
const { status , progress , completedAt } = await response . json ();
return { status , progress , completedAt };
}
let trainingComplete = false ;
while ( ! trainingComplete ) {
const status = await checkTrainingStatus ( job . jobId );
if ( status . status === 'completed' ) {
console . log ( 'AI training complete!' );
trainingComplete = true ;
} else if ( status . status === 'failed' ) {
throw new Error ( 'Training failed' );
} else {
console . log ( `Training progress: ${ status . progress } %` );
await new Promise ( resolve => setTimeout ( resolve , 10000 ));
}
}
Webhooks
Webhooks allow RespondeIA to notify your application of events in real-time.
Available Events
type WebhookEvent =
| 'message.received'
| 'message.sent'
| 'message.delivered'
| 'message.read'
| 'message.failed'
| 'payment.created'
| 'payment.approved'
| 'payment.rejected'
| 'payment.refunded'
| 'customer.created'
| 'customer.updated'
| 'conversation.escalated'
| 'ai.training.completed' ;
Creating a Webhook
interface WebhookConfig {
url : string ;
events : WebhookEvent [];
secret ?: string ;
}
async function createWebhook ( config : WebhookConfig ) {
const response = await fetch ( 'https://api.respondeia.com/v1/webhooks' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( config )
});
const { webhookId , secret } = await response . json ();
return { webhookId , secret };
}
// Example: Create webhook for messages and payments
const webhook = await createWebhook ({
url: 'https://yourdomain.com/webhooks/respondeia' ,
events: [
'message.received' ,
'message.sent' ,
'payment.approved' ,
'payment.rejected'
]
});
console . log ( `Webhook created: ${ webhook . webhookId } ` );
console . log ( `Secret: ${ webhook . secret } ` );
Webhook Payload
interface WebhookPayload {
event : WebhookEvent ;
timestamp : number ;
data : any ;
signature : string ;
}
// Example payload for message.received
{
"event" : "message.received" ,
"timestamp" : 1678886400 ,
"data" : {
"message_id" : "msg_abc123" ,
"customer_id" : "wa:5491123456789" ,
"content" : "Hola, quiero información sobre precios" ,
"channel" : "whatsapp" ,
"received_at" : 1678886400
},
"signature" : "sha256=abc123..."
}
Verifying Webhook Signatures
import crypto from 'crypto' ;
function verifyWebhookSignature (
payload : string ,
signature : string ,
secret : string
) : boolean {
const expectedSignature = crypto
. createHmac ( 'sha256' , secret )
. update ( payload )
. digest ( 'hex' );
return signature === `sha256= ${ expectedSignature } ` ;
}
// Express.js example
app . post ( '/webhooks/respondeia' , ( req , res ) => {
const signature = req . headers [ 'x-respondeia-signature' ] as string ;
const payload = JSON . stringify ( req . body );
if ( ! verifyWebhookSignature ( payload , signature , webhookSecret )) {
return res . status ( 401 ). json ({ error: 'Invalid signature' });
}
const event : WebhookPayload = req . body ;
switch ( event . event ) {
case 'message.received' :
console . log ( 'New message:' , event . data . content );
break ;
case 'payment.approved' :
console . log ( 'Payment approved:' , event . data . payment_id );
break ;
// Handle other events
}
res . status ( 200 ). json ({ received: true });
});
Endpoints that return lists use cursor-based pagination:
interface PaginatedResponse < T > {
data : T [];
hasMore : boolean ;
nextCursor ?: string ;
}
async function fetchAllPages < T >(
endpoint : string ,
limit : number = 100
) : Promise < T []> {
const allResults : T [] = [];
let cursor : string | undefined ;
do {
const params = new URLSearchParams ({
limit: limit . toString (),
... ( cursor && { cursor })
});
const response = await fetch ( ` ${ endpoint } ? ${ params } ` , {
headers: {
'Authorization' : `Bearer ${ apiKey } `
}
});
const page : PaginatedResponse < T > = await response . json ();
allResults . push ( ... page . data );
cursor = page . nextCursor ;
} while ( cursor );
return allResults ;
}
// Example: Fetch all customers
const allCustomers = await fetchAllPages ( '/v1/customers' , 100 );
console . log ( `Total customers: ${ allCustomers . length } ` );
SDKs and Libraries
Official SDKs are available for popular languages:
TypeScript/Node.js npm install @respondeia/sdk
PHP composer require respondeia/sdk
Using the TypeScript SDK
import { RespondeIA } from '@respondeia/sdk' ;
const client = new RespondeIA ({
apiKey: process . env . RESPONDEIA_API_KEY
});
// Send message
await client . messages . send ({
channel: 'whatsapp' ,
to: 'wa:5491123456789' ,
content: 'Hola!'
});
// Create payment
const payment = await client . payments . create ({
customerId: 'wa:5491123456789' ,
amount: 5900 ,
description: 'Plan Pro'
});
// Get analytics
const metrics = await client . analytics . getDashboard ({
period: '7d'
});
Best Practices
1. Use Webhooks Instead of Polling
Good Use webhooks to receive real-time notifications
Avoid Polling endpoints repeatedly wastes requests
2. Implement Exponential Backoff
async function fetchWithRetry (
url : string ,
options : RequestInit ,
maxRetries : number = 3
) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
const response = await fetch ( url , options );
if ( response . ok ) {
return response ;
}
// Don't retry client errors (4xx)
if ( response . status >= 400 && response . status < 500 ) {
throw new Error ( `Client error: ${ response . status } ` );
}
} catch ( error ) {
if ( i === maxRetries - 1 ) throw error ;
// Exponential backoff: 1s, 2s, 4s
const delay = Math . pow ( 2 , i ) * 1000 ;
await new Promise ( resolve => setTimeout ( resolve , delay ));
}
}
}
3. Cache Responses When Possible
const cache = new Map < string , { data : any ; expiresAt : number }>();
async function cachedFetch ( url : string , ttl : number = 60000 ) {
const now = Date . now ();
const cached = cache . get ( url );
if ( cached && cached . expiresAt > now ) {
return cached . data ;
}
const response = await fetch ( url , {
headers: { 'Authorization' : `Bearer ${ apiKey } ` }
});
const data = await response . json ();
cache . set ( url , { data , expiresAt: now + ttl });
return data ;
}
4. Handle Idempotency
Use idempotency keys for critical operations:
import { v4 as uuidv4 } from 'uuid' ;
async function createPaymentIdempotent (
customerId : string ,
amount : number ,
description : string
) {
const idempotencyKey = uuidv4 ();
const response = await fetch ( 'https://api.respondeia.com/v1/payments/create' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json' ,
'Idempotency-Key' : idempotencyKey
},
body: JSON . stringify ({
customer_id: customerId ,
amount ,
description
})
});
return response . json ();
}
Testing
Test Mode
Use test API keys for development:
const testApiKey = 'test_sk_abc123...' ;
// Test keys are prefixed with 'test_'
// They don't affect production data
Mock Server
RespondeIA provides a mock server for testing:
# Install mock server
npm install -g @respondeia/mock-server
# Run locally
respondeia-mock --port 3000
# Point your code to mock server
const baseUrl = 'http://localhost:3000/v1' ;
Support
If you encounter issues with the API:
Documentation Browse complete documentation
Status Page Check API status: status.respondeia.com
GitHub Report issues and request features
Next Steps
WhatsApp Integration Set up WhatsApp Business API
MercadoPago Integration Enable payment processing
Webhooks Guide Configure real-time notifications
AI Training Train your AI assistant