Why Use the Chat API?
The FAQ Ally Chat API allows you to integrate AI agents directly into your custom applications, websites, and mobile apps. Unlike widgets, which provide a pre-built chat interface, the API gives you full control over the user experience, allowing you to create custom interfaces that match your brand and workflow.
The API is secure, easy to use, and includes built-in image support. Responses automatically include relevant images from your training documents when available.
API Overview
๐ Endpoint
POST https://faqally.com/api/agents/{agentId}/chat Replace {agentId} with your AI agent's ID.
๐ Authentication
The Chat API uses API key authentication. Include your API key in the Authorization header:
Authorization: Bearer sk_live_your_api_key_here You can also use the X-API-Key header:
X-API-Key: sk_live_your_api_key_here๐ Request Format
Content-Type: application/json
{
"message": "What is your return policy?"
}โ Response Format
{
"success": true,
"response": "Our return policy allows returns within 30 days of purchase...",
"response_format": "plain",
"confidence": 0.95,
"citations": ["Return_Policy.pdf", "Terms_of_Service.pdf"],
"imageRefs": [
"507f1f77bcf86cd799439011",
"507f191e810c19729de860ea"
]
}The response includes:
success: Boolean indicating if the request succeededresponse: The AI-generated text responseresponse_format: Either"plain"or"markdown", indicating the format of the response (see Optional Markdown section)confidence: Score (0.0 to 1.0) indicating how well the response matches your training datacitations: Array of file names that were used as sources for the responseimageRefs: Array of image IDs that are relevant to the response (backward compatibility)imageUrls: Array of full image URLs ready to use (includes API key authentication)
Getting Started
1 Create an API Key
Click Edit on an agent card to open the agent wizard. In Advanced Mode, navigate to the API Setup step and click "Generate New Key".
Important: Copy the full API key immediatelyโit's only shown once! Store it securely and never expose it in client-side code or commit it to version control.
2 Configure Domain Verification
Domain verification restricts API access to authorized domains. Configure it at the agent levelโthe same DNS TXT record works for both widgets and API keys. See the Domain Verification guide for setup instructions.
3 Make Your First API Request
Use the API key to send chat messages to your AI agent. Here's a simple cURL example:
curl -X POST https://faqally.com/api/agents/YOUR_AGENT_ID/chat \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"message": "What is your return policy?"}'Optional Markdown
Agents can be configured to return responses in either Plain Text or Markdown format. The API response includes a response_format field indicating which format was used.
๐ Response Format Field
Check the response_format field in the API response:
{
"success": true,
"response": "Here's a **formatted** response with *markdown*...",
"response_format": "markdown",
"confidence": 0.95
}Or for plain text:
{
"success": true,
"response": "Here's a plain text response with paragraph breaks.",
"response_format": "plain",
"confidence": 0.95
}๐ง Consuming Markdown Responses
If response_format is "markdown", use a markdown parser to render the response as HTML. If it's "plain", display the text directly with preserved line breaks.
JavaScript Example:
const data = await response.json();
if (data.response_format === 'markdown') {
// Render markdown to HTML (e.g., using marked library)
const html = marked.parse(data.response);
document.getElementById('chat-response').innerHTML = html;
} else {
// Display plain text with preserved line breaks
const text = document.createTextNode(data.response);
const pre = document.createElement('pre');
pre.style.whiteSpace = 'pre-wrap';
pre.appendChild(text);
document.getElementById('chat-response').appendChild(pre);
}Python Example:
import markdown # or mistune, markdown2, etc.
data = response.json()
if data.get('response_format') == 'markdown':
# Render markdown to HTML
html = markdown.markdown(data['response'])
return html
else:
# Display plain text with preserved whitespace
return data['response'].replace('\n\n', '<br><br>')Note: Markdown format includes support for bold, italic, lists, headings, code blocks, and blockquotes. Always sanitize HTML output when rendering markdown to prevent XSS attacks.
Handling Images
When responses include relevant images, the API returns imageUrlsโan array of ready-to-use image URLs with authentication included.
{
"success": true,
"response": "Here's how to perform the chemical reaction...",
"imageUrls": [
"https://faqally.com/api/agents/agent123/images/abc123?api_key=sk_live_...",
"https://faqally.com/api/agents/agent123/images/def456?api_key=sk_live_..."
]
}Usage: Use imageUrls directlyโno URL construction needed. Display them in your UI like any other image URL.
Note: Image URLs include your API key in the query parameter (required for <img> tags). They may appear in browser history and server logs.
Code Examples
๐ป JavaScript (Node.js / Server-Side)
const axios = require('axios');
async function chatWithAgent(message) {
try {
const response = await axios.post(
'https://faqally.com/api/agents/YOUR_AGENT_ID/chat',
{ message },
{
headers: {
'Authorization': 'Bearer sk_live_your_api_key_here',
'Content-Type': 'application/json'
}
}
);
console.log('Response:', response.data.response);
console.log('Confidence:', response.data.confidence);
console.log('Citations:', response.data.citations);
if (response.data.imageRefs) {
console.log('Images:', response.data.imageRefs);
}
return response.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
throw error;
}
}
// Usage
chatWithAgent('What is your return policy?');๐ Python
import requests
def chat_with_agent(message):
url = 'https://faqally.com/api/agents/YOUR_AGENT_ID/chat'
headers = {
'Authorization': 'Bearer sk_live_your_api_key_here',
'Content-Type': 'application/json'
}
data = {'message': message}
response = requests.post(url, json=data, headers=headers)
response.raise_for_status()
result = response.json()
print(f"Response: {result['response']}")
print(f"Confidence: {result['confidence']}")
print(f"Citations: {result.get('citations', [])}")
if 'imageRefs' in result:
print(f"Images: {result['imageRefs']}")
return result
# Usage
chat_with_agent('What is your return policy?')๐ต C# / .NET
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class FaqAllyClient
{
private readonly HttpClient _httpClient;
private readonly string _apiKey;
private readonly string _agentId;
public FaqAllyClient(string apiKey, string agentId)
{
_httpClient = new HttpClient();
_apiKey = apiKey;
_agentId = agentId;
_httpClient.BaseAddress = new Uri("https://faqally.com");
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
}
public async Task<ChatResponse> ChatAsync(string message)
{
var request = new { message };
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(
$"/api/agents/{_agentId}/chat",
content
);
response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<ChatResponse>(responseJson);
}
}
public class ChatResponse
{
public bool Success { get; set; }
public string Response { get; set; }
public double Confidence { get; set; }
public List<string> Citations { get; set; }
public List<string> ImageRefs { get; set; }
}Security Best Practices
- Never expose API keys in client-side code: Always call the API from your backend server
- Use environment variables: Store API keys securely, never in code
- Enable domain verification: Restricts API access to authorized domains even if a key is compromised
- Rotate keys regularly: Regenerate API keys periodically
Recommended Pattern: Frontend โ Your Backend API โ FAQ Ally API. This keeps API keys secure on your server.
Rate Limiting
API keys have built-in rate limiting to protect your resources:
- Default: 60 requests per minute per API key
- Company limits: Respects your plan's query limits
- Rate limit exceeded: Returns 429 Too Many Requests
If you need higher rate limits, contact support to discuss your requirements.
Error Handling
๐ Common Error Responses
- 401 Unauthorized: Invalid or inactive API key
- 403 Forbidden: Domain not authorized or plan limit exceeded
- 400 Bad Request: Invalid request format or missing message
- 404 Not Found: Agent not found
- 429 Too Many Requests: Rate limit exceeded
- 500 Internal Server Error: Server error (try again later)
๐ Error Response Format
{
"success": false,
"error": "Error Type",
"message": "Human-readable error message"
}Next Steps
Now that you understand the Chat API, you're ready to integrate FAQ Ally into your applications:
