API Reference
Responses
Understanding API response formats, status codes, and error handling for Yachtsy Agent.
Overview
All Yachtsy Agent API endpoints return responses in JSON format, following OpenAI's response structure for maximum compatibility.
Response Format
Successful Responses
All successful API responses follow this general structure:
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1677652288,
"model": "yachtsy-agent",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Your sailing question response here..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 56,
"completion_tokens": 31,
"total_tokens": 87
}
}
Response Fields
Core Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the completion |
object | string | The object type (e.g., "chat.completion") |
created | integer | Unix timestamp of when the completion was created |
model | string | The model used for the completion |
Choices Array
| Field | Type | Description |
|---|---|---|
index | integer | The index of the choice in the list |
message | object | The generated message |
message.role | string | Always "assistant" for completions |
message.content | string | The actual response content |
finish_reason | string | Reason the model stopped generating |
Usage Object
| Field | Type | Description |
|---|---|---|
prompt_tokens | integer | Number of tokens in the prompt |
completion_tokens | integer | Number of tokens in the completion |
total_tokens | integer | Total tokens used (prompt + completion) |
Finish Reasons
| Reason | Description |
|---|---|
stop | Natural stopping point or provided stop sequence |
length | Maximum token limit reached |
content_filter | Content filtered due to policy violations |
Streaming Responses
When using stream: true, responses are sent as Server-Sent Events (SSE):
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1677652288,"model":"yachtsy-agent","choices":[{"index":0,"delta":{"role":"assistant","content":"For"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1677652288,"model":"yachtsy-agent","choices":[{"index":0,"delta":{"content":" Caribbean"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1677652288,"model":"yachtsy-agent","choices":[{"index":0,"delta":{"content":" sailing"},"finish_reason":null}]}
data: [DONE]
Streaming Format
- Each chunk contains a
deltaobject with incremental content - The final chunk has
finish_reasonset and emptydelta - Stream ends with
data: [DONE]
HTTP Status Codes
Success Codes
| Code | Status | Description |
|---|---|---|
200 | OK | Request successful |
201 | Created | Resource created successfully |
Client Error Codes
| Code | Status | Description |
|---|---|---|
400 | Bad Request | Invalid request format or parameters |
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | Access denied for this resource |
404 | Not Found | Endpoint or resource not found |
422 | Unprocessable Entity | Request valid but cannot be processed |
429 | Too Many Requests | Rate limit exceeded |
Server Error Codes
| Code | Status | Description |
|---|---|---|
500 | Internal Server Error | Unexpected server error |
502 | Bad Gateway | Upstream service error |
503 | Service Unavailable | Service temporarily unavailable |
Error Response Format
Error responses follow OpenAI's error format:
{
"error": {
"message": "Invalid API key provided",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}
Error Types
| Type | Description |
|---|---|
invalid_request_error | Invalid request parameters |
authentication_error | Authentication failed |
permission_error | Insufficient permissions |
not_found_error | Resource not found |
rate_limit_error | Rate limit exceeded |
api_error | Server-side error |
Common Error Codes
| Code | Description |
|---|---|
invalid_api_key | The provided API key is invalid |
missing_api_key | No API key provided |
model_not_found | Requested model doesn't exist |
context_length_exceeded | Request exceeds maximum context length |
rate_limit_exceeded | Too many requests in time window |
Response Examples
Chat Completion Success
{
"id": "chatcmpl-yachtsy123",
"object": "chat.completion",
"created": 1677652288,
"model": "yachtsy-agent",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "For Caribbean sailing, I'd recommend the Jeanneau Sun Odyssey 409 or Beneteau Oceanis 40.1. Both offer excellent blue water capabilities with shallow drafts perfect for Caribbean anchorages. The Sun Odyssey 409 has superior upwind performance, while the Oceanis 40.1 offers more interior space."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 28,
"completion_tokens": 52,
"total_tokens": 80
}
}
Models List Success
{
"object": "list",
"data": [
{
"id": "yachtsy-agent",
"object": "model",
"created": 1677610602,
"owned_by": "yachtsy"
},
{
"id": "yachtsy-deep-research-agent",
"object": "model",
"created": 1677610602,
"owned_by": "yachtsy"
}
]
}
Authentication Error
{
"error": {
"message": "Invalid API key provided. Please check your API key and try again.",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}
Rate Limit Error
{
"error": {
"message": "Rate limit exceeded. Please wait before making another request.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
}
}
Best Practices
Error Handling
Always check the HTTP status code and handle errors appropriately:
import requests
try:
response = requests.post(
"http://api.yachtsy.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}"},
json=payload
)
response.raise_for_status() # Raises HTTPError for bad responses
data = response.json()
except requests.exceptions.HTTPError as e:
if response.status_code == 401:
print("Invalid API key")
elif response.status_code == 429:
print("Rate limit exceeded - please wait")
else:
error_data = response.json()
print(f"API Error: {error_data['error']['message']}")
Retry Logic
Implement exponential backoff for rate limits and server errors:
import time
import random
def make_request_with_retry(url, payload, max_retries=3):
for attempt in range(max_retries):
try:
response = requests.post(url, json=payload)
if response.status_code == 429:
# Rate limit - wait and retry
wait_time = (2 ** attempt) + random.uniform(0, 1)
time.sleep(wait_time)
continue
return response
except requests.exceptions.RequestException:
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt)
Response Validation
Always validate response structure before using:
def validate_completion_response(response_data):
required_fields = ['id', 'object', 'choices']
for field in required_fields:
if field not in response_data:
raise ValueError(f"Missing required field: {field}")
if not response_data['choices']:
raise ValueError("No choices in response")
choice = response_data['choices'][0]
if 'message' not in choice or 'content' not in choice['message']:
raise ValueError("Invalid choice format")
return choice['message']['content']