API Integration
Connect your Xano backend to external services using the SDK’s comprehensive API request capabilities. Make HTTP requests, handle responses, and integrate with third-party APIs.
Basic HTTP Requests
GET Requests
Fetch data from external APIs:
.apiRequest(
'https://api.example.com/users',
'GET',
{
params: {
page: '$input.page',
limit: 20
},
headers: [
{ key: 'Authorization', value: 'Bearer $api_key' }
]
},
'api_response'
)
The response is stored in the specified alias and contains:
response.status- HTTP status coderesponse.data- Response bodyresponse.headers- Response headers
POST Requests
Send data to external APIs:
.apiRequest(
'https://api.example.com/users',
'POST',
{
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'Authorization', value: 'Bearer $api_key' }
],
body: {
name: '$input.name',
email: '$input.email',
role: 'user'
}
},
'create_response'
)
PUT and PATCH Requests
Update resources on external APIs:
.apiRequest(
'https://api.example.com/users/$input.user_id',
'PUT',
{
headers: [
{ key: 'Content-Type', value: 'application/json' },
{ key: 'Authorization', value: 'Bearer $api_key' }
],
body: {
name: '$input.name',
email: '$input.email',
updated_at: 'now'
}
},
'update_response'
)
DELETE Requests
Remove resources from external APIs:
.apiRequest(
'https://api.example.com/users/$input.user_id',
'DELETE',
{
headers: [
{ key: 'Authorization', value: 'Bearer $api_key' }
]
},
'delete_response'
)
Request Configuration
Headers
Add custom headers to your requests:
.apiRequest(
'https://api.example.com/data',
'GET',
{
headers: [
{ key: 'Authorization', value: 'Bearer $env.API_KEY' },
{ key: 'X-Custom-Header', value: '$input.custom_value' },
{ key: 'Accept', value: 'application/json' }
]
},
'response'
)
Query Parameters
Add query parameters to GET requests:
.apiRequest(
'https://api.example.com/search',
'GET',
{
params: {
q: '$input.search',
category: '$input.category',
limit: 50,
offset: '$input.offset'
}
},
'search_results'
)
The URL will be constructed as:
https://api.example.com/search?q=value&category=electronics&limit=50&offset=0
Request Body
Send JSON data in POST, PUT, and PATCH requests:
.apiRequest(
'https://api.example.com/orders',
'POST',
{
headers: [
{ key: 'Content-Type', value: 'application/json' }
],
body: {
user_id: '$auth.id',
items: '$cart.items',
total: '$calculated_total',
shipping_address: '$input.address'
}
},
'order_response'
)
Timeouts
Set request timeouts to prevent hanging:
.apiRequest(
'https://slow-api.example.com/data',
'GET',
{
timeout: 5000 // 5 seconds
},
'response'
)
Response Handling
Checking Status Codes
Verify the response was successful:
.apiRequest(
'https://api.example.com/data',
'GET',
{},
'api_response'
)
.conditional('$api_response.response.status == 200')
.then()
.var('data', 'object', '$api_response.response.data')
.response({ data: '$data' })
.else()
.return({ error: 'API request failed' })
.endConditional()
Extracting Response Data
Access specific fields from the API response:
.apiRequest(
'https://api.weather.com/current',
'GET',
{
params: { city: '$input.city' }
},
'weather_response'
)
.var('temperature', 'decimal', '$weather_response.response.data.temp')
.var('condition', 'text', '$weather_response.response.data.condition')
.response({
temperature: '$temperature',
condition: '$condition',
city: '$input.city'
})
Error Handling
Handle API errors gracefully:
.apiRequest(
'https://api.example.com/data',
'GET',
{},
'api_response'
)
.conditional('$api_response.response.status >= 400')
.then()
.var('error_message', 'text', '$api_response.response.data.message')
.return({
error: '$error_message',
status: '$api_response.response.status'
})
.endConditional()
// Continue with successful response
.response({
data: '$api_response.response.data'
})
GraphQL Integration
Basic GraphQL Queries
Query GraphQL APIs:
.graphqlRequest(
'https://api.example.com/graphql',
`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
title
content
}
}
}
`,
{
id: '$input.user_id'
},
[
{ key: 'Authorization', value: 'Bearer $api_key' }
],
'graphql_response'
)
.response({
user: '$graphql_response.response.data.user'
})
GraphQL Mutations
Modify data through GraphQL:
.graphqlRequest(
'https://api.example.com/graphql',
`
mutation CreatePost($title: String!, $content: String!) {
createPost(title: $title, content: $content) {
id
title
createdAt
}
}
`,
{
title: '$input.title',
content: '$input.content'
},
[
{ key: 'Authorization', value: 'Bearer $auth.token' }
],
'create_response'
)
.response({
post: '$create_response.response.data.createPost'
})
Common Integration Patterns
Weather API Integration
Fetch weather data from external service:
const weatherEndpoint = XanoScript.create('integrations/weather', 'GET')
.description('Get current weather for a city')
.input('city', 'text', { required: true })
.var('api_key', 'text', 'env.WEATHER_API_KEY')
.apiRequest(
'https://api.openweathermap.org/data/2.5/weather',
'GET',
{
params: {
q: '$input.city',
appid: '$api_key',
units: 'metric'
}
},
'weather_response'
)
.conditional('$weather_response.response.status == 200')
.then()
.response({
temperature: '$weather_response.response.data.main.temp',
description: '$weather_response.response.data.weather[0].description',
humidity: '$weather_response.response.data.main.humidity',
city: '$weather_response.response.data.name'
})
.else()
.return({ error: 'Failed to fetch weather data' })
.endConditional();
Stripe Payment Processing
Create a payment intent:
const createPayment = XanoScript.create('payments/create', 'POST')
.description('Create Stripe payment intent')
.requiresAuth('users')
.input('amount', 'int', { required: true })
.input('currency', 'text', { default: 'usd' })
.var('stripe_key', 'text', 'env.STRIPE_SECRET_KEY')
.apiRequest(
'https://api.stripe.com/v1/payment_intents',
'POST',
{
headers: [
{ key: 'Authorization', value: 'Bearer $stripe_key' },
{ key: 'Content-Type', value: 'application/x-www-form-urlencoded' }
],
body: {
amount: '$input.amount',
currency: '$input.currency',
metadata: {
user_id: '$auth.id'
}
}
},
'payment_response'
)
.conditional('$payment_response.response.status == 200')
.then()
.var('payment_intent', 'object', '$payment_response.response.data')
// Save to database
.dbAdd('"payments"', {
user_id: '$auth.id',
stripe_payment_intent_id: '$payment_intent.id',
amount: '$input.amount',
currency: '$input.currency',
status: '$payment_intent.status',
created_at: 'now'
}, 'payment_record')
.response({
client_secret: '$payment_intent.client_secret',
payment_id: '$payment_record.id'
})
.else()
.return({ error: 'Failed to create payment intent' })
.endConditional();
Slack Notifications
Send messages to Slack:
const sendSlackNotification = XanoScript.create('notifications/slack', 'POST')
.description('Send notification to Slack channel')
.requiresAuth('users')
.input('message', 'text', { required: true })
.input('channel', 'text', { default: '#general' })
.var('webhook_url', 'text', 'env.SLACK_WEBHOOK_URL')
.apiRequest(
'$webhook_url',
'POST',
{
headers: [
{ key: 'Content-Type', value: 'application/json' }
],
body: {
channel: '$input.channel',
text: '$input.message',
username: 'Xano Bot',
icon_emoji: ':robot_face:'
}
},
'slack_response'
)
.conditional('$slack_response.response.status == 200')
.then()
.response({ sent: true, message: '$input.message' })
.else()
.return({ error: 'Failed to send Slack notification' })
.endConditional();
Email Service Integration
Send emails via SendGrid:
const sendEmail = XanoScript.create('email/send', 'POST')
.description('Send email via SendGrid')
.requiresAuth('users')
.input('to', 'email', { required: true })
.input('subject', 'text', { required: true })
.input('content', 'text', { required: true })
.var('sendgrid_key', 'text', 'env.SENDGRID_API_KEY')
.apiRequest(
'https://api.sendgrid.com/v3/mail/send',
'POST',
{
headers: [
{ key: 'Authorization', value: 'Bearer $sendgrid_key' },
{ key: 'Content-Type', value: 'application/json' }
],
body: {
personalizations: [{
to: [{ email: '$input.to' }]
}],
from: { email: 'noreply@example.com' },
subject: '$input.subject',
content: [{
type: 'text/html',
value: '$input.content'
}]
}
},
'email_response'
)
.conditional('$email_response.response.status == 202')
.then()
.dbAdd('"email_log"', {
user_id: '$auth.id',
to: '$input.to',
subject: '$input.subject',
sent_at: 'now',
status: 'sent'
}, 'log')
.response({ sent: true })
.else()
.return({ error: 'Failed to send email' })
.endConditional();
Authentication Patterns
API Key Authentication
Pass API keys in headers:
.var('api_key', 'text', 'env.EXTERNAL_API_KEY')
.apiRequest(
'https://api.example.com/data',
'GET',
{
headers: [
{ key: 'X-API-Key', value: '$api_key' }
]
},
'response'
)
Bearer Token Authentication
Use bearer tokens for OAuth:
.apiRequest(
'https://api.example.com/user',
'GET',
{
headers: [
{ key: 'Authorization', value: 'Bearer $auth.external_token' }
]
},
'user_data'
)
Basic Authentication
Encode credentials for basic auth:
.var('username', 'text', 'env.API_USERNAME')
.var('password', 'text', 'env.API_PASSWORD')
.var('credentials', 'text', 'base64_encode($username + ":" + $password)')
.apiRequest(
'https://api.example.com/data',
'GET',
{
headers: [
{ key: 'Authorization', value: 'Basic $credentials' }
]
},
'response'
)
Best Practices
Environment Variables
Store sensitive API keys and credentials in environment variables:
.var('api_key', 'text', 'env.EXTERNAL_API_KEY')
.var('api_secret', 'text', 'env.EXTERNAL_API_SECRET')
Never hardcode credentials in your endpoints.
Error Handling
Always check response status codes and handle errors:
.conditional('$api_response.response.status >= 400')
.then()
.return({
error: true,
message: '$api_response.response.data.message',
status: '$api_response.response.status'
})
.endConditional()
Rate Limiting
Respect API rate limits and implement retry logic:
.conditional('$api_response.response.status == 429')
.then()
.return({
error: 'Rate limit exceeded',
retry_after: '$api_response.response.headers.retry-after'
})
.endConditional()
Request Validation
Validate inputs before making external requests:
.precondition('$input.email != null', 'Email is required')
.precondition('$input.amount > 0', 'Amount must be positive')
.apiRequest(...)
Logging
Log API requests for debugging and monitoring:
.apiRequest(
'https://api.example.com/data',
'POST',
{ body: '$input.data' },
'api_response'
)
.dbAdd('"api_logs"', {
endpoint: 'external_api',
request_data: '$input.data',
response_status: '$api_response.response.status',
created_at: 'now'
}, 'log')
Next Steps
- Security & Auth - Secure your API integrations
- Database Operations - Store API responses
- Recipes - Complete integration examples
- API Reference - Full method reference