Cloud API overview
For the available API endpoints, refer to the Faheem Code API Reference.
Obtaining an API key
To use the Faheem Code Cloud API, you'll need to generate an API key:
- Log in to your Faheem Code Cloud account.
- Navigate to the Settings > API Keys page.
- Click
Create API Key. - Give your key a descriptive name (Example: "Development" or "Production") and select
Create. - Copy the generated API key and store it securely. It will only be shown once.
API usage example (V1)
Starting a new conversation
To start a new conversation with Faheem Code to perform a task, make a POST request to the V1 app-conversations endpoint.
curl -X POST "https://app.faheemcode.ai/api/v1/app-conversations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"initial_message": {
"content": [{"type": "text", "text": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so."}]
},
"selected_repository": "yourusername/your-repo"
}'
import requests
api_key = "YOUR_API_KEY"
url = "https://app.faheemcode.ai/api/v1/app-conversations"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
data = {
"initial_message": {
"content": [{"type": "text", "text": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so."}]
},
"selected_repository": "yourusername/your-repo"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
# The response contains a start task with the conversation ID
conversation_id = result.get("app_conversation_id") or result.get("id")
print(f"Conversation Link: https://app.faheemcode.ai/conversations/{conversation_id}")
print(f"Status: {result['status']}")
const apiKey = "YOUR_API_KEY";
const url = "https://app.faheemcode.ai/api/v1/app-conversations";
const headers = {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
};
const data = {
initial_message: {
content: [{ type: "text", text: "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so." }]
},
selected_repository: "yourusername/your-repo"
};
async function startConversation() {
try {
const response = await fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(data)
});
const result = await response.json();
// The response contains a start task with the conversation ID
const conversationId = result.app_conversation_id || result.id;
console.log(`Conversation Link: https://app.faheemcode.ai/conversations/${conversationId}`);
console.log(`Status: ${result.status}`);
return result;
} catch (error) {
console.error("Error starting conversation:", error);
}
}
startConversation();
Optional observability fields
When starting a conversation, you can attach observability context to the trace:
| Field | Type | Description |
|---|---|---|
observability_span_name | string | Creates a named child span under the root conversation span. Use stable, low-cardinality names for grouping and signal routing. |
observability_tags | string array | Adds tags to the conversation root observability span. |
observability_metadata | object | Adds trace-level metadata. Values must be scalars or homogeneous scalar arrays, such as strings, numbers, booleans, string[], number[], or boolean[]. |
Example:
{
"initial_message": {
"content": [
{
"type": "text",
"text": "Evaluate this repository against the WB rubric."
}
]
},
"selected_repository": "yourusername/your-repo",
"observability_span_name": "wb_rubric_eval",
"observability_tags": ["wb-rubric", "evaluation"],
"observability_metadata": {
"evaluation": "wb",
"attempt": 1,
"replay": false
}
}
Response
The API will return a JSON object with details about the conversation start task:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "WORKING",
"app_conversation_id": "660e8400-e29b-41d4-a716-446655440001",
"sandbox_id": "sandbox-abc123",
"created_at": "2025-01-15T10:30:00Z"
}
The status field indicates the current state of the conversation startup process:
WORKING- Initial processingWAITING_FOR_SANDBOX- Waiting for sandbox to be readyPREPARING_REPOSITORY- Cloning and setting up the repositorySETTING_UP_SKILLS- Configuring agent skills and toolsREADY- Conversation is ready to useERROR- An error occurred during startup
You may receive an authentication error if:
- You provided an invalid API key.
- You provided the wrong repository name.
- You don't have access to the repository.
Streaming conversation start (optional)
For real-time updates during conversation startup, you can use the streaming endpoint:
curl -X POST "https://app.faheemcode.ai/api/v1/app-conversations/stream-start" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"initial_message": {
"content": [{"type": "text", "text": "Your task description here"}]
},
"selected_repository": "yourusername/your-repo"
}'
Streaming response
The endpoint streams a JSON array incrementally. Each element represents a status update:
[
{"id": "550e8400-e29b-41d4-a716-446655440000", "status": "WORKING", "created_at": "2025-01-15T10:30:00Z"},
{"id": "550e8400-e29b-41d4-a716-446655440000", "status": "WAITING_FOR_SANDBOX", "created_at": "2025-01-15T10:30:00Z"},
{"id": "550e8400-e29b-41d4-a716-446655440000", "status": "PREPARING_REPOSITORY", "created_at": "2025-01-15T10:30:00Z"},
{"id": "550e8400-e29b-41d4-a716-446655440000", "status": "READY", "app_conversation_id": "660e8400-e29b-41d4-a716-446655440001", "sandbox_id": "sandbox-abc123", "created_at": "2025-01-15T10:30:00Z"}
]
Each update is streamed as it occurs, allowing you to provide real-time feedback to users about the conversation startup progress.
Checking conversation status
After starting a conversation, you can check its status to monitor whether the agent has completed its task.
Step 1: check start task status
When you start a conversation, you receive a start task ID. Poll this endpoint until status becomes READY and app_conversation_id is available:
curl -X GET "https://app.faheemcode.ai/api/v1/app-conversations/start-tasks?ids=TASK_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "READY",
"app_conversation_id": "660e8400-e29b-41d4-a716-446655440001",
"sandbox_id": "sandbox-abc123"
}
Step 2: check conversation execution status
Once you have the app_conversation_id, check whether the agent has finished its task:
curl -X GET "https://app.faheemcode.ai/api/v1/app-conversations?ids=CONVERSATION_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
api_key = "YOUR_API_KEY"
conversation_id = "YOUR_CONVERSATION_ID"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.get(
"https://app.faheemcode.ai/api/v1/app-conversations",
headers=headers,
params={"ids": conversation_id}
)
response.raise_for_status() # Raise exception for HTTP errors
conversations = response.json()
if conversations:
conv = conversations[0]
print(f"Sandbox Status: {conv.get('sandbox_status')}")
print(f"Execution Status: {conv.get('execution_status')}")
else:
print("Conversation not found")
Response:
[
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"sandbox_status": "RUNNING",
"execution_status": "finished",
"selected_repository": "yourusername/your-repo",
"title": "Fix README"
}
]
Status fields
sandbox_status - The state of the sandbox environment:
STARTING- Sandbox is being created. Action: Continue polling.RUNNING- Sandbox is active. Action: Checkexecution_statusfor task progress.PAUSED- Sandbox is paused (due to rate limits or user action). Action: The sandbox will resume automatically when resources are available, or resume manually via the UI.ERROR- Sandbox encountered an error. Action: This is a terminal state. Check conversation details in the UI for error information.MISSING- Sandbox was deleted. Action: This is a terminal state. Start a new conversation if needed.
execution_status - The state of the agent's task (available when sandbox is RUNNING):
idle- Agent is ready to receive tasks. Action: Continue polling if task was recently submitted.running- Agent is actively working. Action: Continue polling.paused- Execution is paused. Action: Continue polling; will resume automatically.waiting_for_confirmation- Agent is waiting for user confirmation. Action: This is a blocking state. The agent needs user input via the UI to proceed. Your polling loop should treat this as a terminal state or alert the user.finished- Agent has completed the task. Action: Terminal state. Task is done successfully.error- Agent encountered an error. Action: Terminal state. Check conversation in UI for error details.stuck- Agent is stuck and unable to proceed. Action: Terminal state. Manual intervention may be required.
Complete polling example
Here's a complete example that starts a conversation and polls until completion:
import requests
import time
api_key = "YOUR_API_KEY"
base_url = "https://app.faheemcode.ai"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Start a conversation
print("Starting conversation...")
start_response = requests.post(
f"{base_url}/api/v1/app-conversations",
headers=headers,
json={
"initial_message": {
"content": [{"type": "text", "text": "Your task here"}]
},
"selected_repository": "yourusername/your-repo"
}
)
start_response.raise_for_status()
start_task = start_response.json()
task_id = start_task["id"]
print(f"Start task ID: {task_id}")
# Poll start task until conversation is ready (with timeout)
conversation_id = None
max_attempts = 60 # 5 minutes with 5-second intervals
attempts = 0
while not conversation_id and attempts < max_attempts:
task_response = requests.get(
f"{base_url}/api/v1/app-conversations/start-tasks",
headers=headers,
params={"ids": task_id}
)
task_response.raise_for_status()
tasks = task_response.json()
if tasks and tasks[0].get("status") == "READY":
conversation_id = tasks[0].get("app_conversation_id")
print(f"Conversation ready: {base_url}/conversations/{conversation_id}")
elif tasks and tasks[0].get("status") == "ERROR":
print(f"Start task failed: {tasks[0].get('error', 'Unknown error')}")
exit(1)
else:
status = tasks[0].get("status") if tasks else "no response"
print(f"Start task status: {status}")
time.sleep(5)
attempts += 1
if not conversation_id:
print("Timeout waiting for conversation to start")
exit(1)
# Poll conversation until agent finishes (with timeout)
# Terminal states: finished, error, stuck, waiting_for_confirmation
max_attempts = 120 # 1 hour with 30-second intervals
attempts = 0
while attempts < max_attempts:
conv_response = requests.get(
f"{base_url}/api/v1/app-conversations",
headers=headers,
params={"ids": conversation_id}
)
conv_response.raise_for_status()
conversations = conv_response.json()
if not conversations:
print("Warning: Conversation not found")
time.sleep(30)
attempts += 1
continue
conv = conversations[0]
sandbox_status = conv.get("sandbox_status")
exec_status = conv.get("execution_status")
# Check sandbox health first
if sandbox_status in ["ERROR", "MISSING"]:
print(f"Sandbox failed with status: {sandbox_status}")
exit(1)
print(f"Execution status: {exec_status}")
# Check for terminal states
if exec_status in ["finished", "error", "stuck"]:
print(f"Conversation completed with status: {exec_status}")
break
elif exec_status == "waiting_for_confirmation":
print("Agent is waiting for user confirmation in the UI")
print(f"Visit: {base_url}/conversations/{conversation_id}")
break
time.sleep(30)
attempts += 1
else:
print("Timeout waiting for conversation to complete")
exit(1)
Listing all conversations
To list all your conversations, use the search endpoint:
curl -X GET "https://app.faheemcode.ai/api/v1/app-conversations/search?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
api_key = "YOUR_API_KEY"
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(
"https://app.faheemcode.ai/api/v1/app-conversations/search",
headers=headers,
params={"limit": 20}
)
response.raise_for_status()
result = response.json()
for conv in result.get("items", []):
print(f"ID: {conv['id']}, Status: {conv.get('execution_status')}")
Response:
{
"items": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"sandbox_status": "RUNNING",
"execution_status": "finished",
"selected_repository": "yourusername/your-repo",
"title": "Fix README"
}
],
"next_page_id": null
}
Rate limits
If you have too many conversations running at once, older conversations will be paused to limit the number of concurrent conversations. If you're running into issues and need a higher limit for your use case, please contact us at support@faheemcode.ai.
Migrating from V0 to V1 API
Key differences
| Feature | V0 API | V1 API |
|---|---|---|
| Endpoint | POST /api/conversations | POST /api/v1/app-conversations |
| Message format | initial_user_msg (string) | initial_message.content (array of content objects) |
| Repository field | repository | selected_repository |
| Response | Immediate conversation_id | Start task with status and eventual app_conversation_id |
Migration steps
-
Update the endpoint URL: Change from
/api/conversationsto/api/v1/app-conversations -
Update the request body:
- Change
repositorytoselected_repository - Change
initial_user_msg(string) toinitial_message(object with content array):
// V0 format{ "initial_user_msg": "Your message here" }// V1 format{ "initial_message": { "content": [{"type": "text", "text": "Your message here"}] } } - Change
-
Update response handling: The V1 API returns a start task object. The conversation ID is in the
app_conversation_idfield (available when status isREADY), or use theidfield for the start task ID.