Skip to main content

API Resources

Our API is organized around REST principles with predictable, resource-oriented URLs.

Base URL

https://api.happenstance.ai

Authentication

All requests require an API key passed in the Authorization header:
Authorization: Bearer YOUR_API_KEY
API keys are sensitive credentials. Never share them publicly or commit them to version control.

Billing

Our API consumes credits for Search and Research operations:
  • Search: 2 credits per search request (charged when search completes)
  • Research: 1 credit per successful, completed research
You can add credits at any time from your Settings page. You can also monitor your credits from the Settings page, or via the API’s Get Usage endpoint.

Error Response Format

All errors follow the RFC 7807 Problem Details format:
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "Description must not be empty",
  "instance": "/v1/research"
}
FieldDescription
typeA URI reference that identifies the problem type
titleA short, human-readable summary of the problem
statusThe HTTP status code
detailA human-readable explanation specific to this occurrence
instanceA URI reference that identifies the specific occurrence

HTTP Status Codes

2xx Success

CodeDescription
200 OKRequest succeeded

4xx Client Errors

The request was malformed or contains invalid parameters.Common Causes:
  • Missing required fields
  • Invalid JSON format
  • Empty or invalid values
Example:
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "Description must not be empty",
  "instance": "/v1/research"
}
Solution: Check your request body against the API documentation
Authentication failed - your API key is invalid or missing.Common Causes:
  • Missing Authorization header
  • Invalid API key
  • Revoked API key
Example:
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid API key",
  "instance": "/v1/research"
}
Solution: Verify your API key is correct and not revoked
You don’t have enough credits to perform this operation.Common Causes:
  • Account has zero credits
  • Insufficient credits for the requested operation
Example:
{
  "type": "about:blank",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits. You have 0 credits. This operation requires 2 credit(s).",
  "instance": "/v1/search"
}
Solution: Purchase more credits from your Settings page
You don’t have permission to access the requested resource.Common Causes:
  • Attempting to access another user’s research
  • Insufficient permissions for the operation
Example:
{
  "type": "about:blank",
  "title": "Forbidden",
  "status": 403,
  "detail": "Access denied",
  "instance": "/v1/research/550e8400-e29b-41d4-a716-446655440000"
}
Solution: Verify you have access to the resources you’re requesting
The requested resource doesn’t exist.Common Causes:
  • Invalid endpoint URL
  • Resource has been deleted
  • Wrong research ID
Example:
{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "Research request not found",
  "instance": "/v1/research/550e8400-e29b-41d4-a716-446655440000"
}
Solution: Check the resource ID and endpoint URL
The request body failed validation.Common Causes:
  • Missing required fields
  • Invalid field types
  • Fields that don’t match expected format
Example:
{
  "type": "about:blank",
  "title": "Validation Error",
  "status": 422,
  "detail": "Field 'description' is required",
  "instance": "/v1/research"
}
Solution: Ensure all required fields are present and correctly formatted
You’ve exceeded the rate limit.Common Causes:
  • Making too many research requests per hour
  • Burst of requests in short time period
Example:
{
  "type": "about:blank",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Try again in 30 minutes.",
  "instance": "/v1/research"
}
Solution: Implement exponential backoff and respect rate limits

5xx Server Errors

Something went wrong on our end.Example:
{
  "type": "about:blank",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "Internal server error",
  "instance": "/v1/research"
}
Solution:
  • Retry the request with exponential backoff
  • If the issue persists, contact us on Discord
The API is temporarily unavailable.Common Causes:
  • Scheduled maintenance
  • Temporary outage
  • Database connection issues
Solution:
  • Check our status page
  • Retry with exponential backoff

Error Handling Best Practices

Check Status Codes

Always check the HTTP status code before parsing the response:
response = requests.post(url, headers=headers, json=data)

if response.status_code == 200:
    result = response.json()
    # Handle success
elif response.status_code == 401:
    # Handle authentication error
    print("Invalid API key")
elif response.status_code == 402:
    # Handle insufficient credits
    print("Insufficient credits - purchase more at happenstance.ai/api/keys")
elif response.status_code == 429:
    # Handle rate limit
    print("Rate limited, retry later")
else:
    # Handle other errors
    error = response.json()
    print(f"Error: {error.get('title')} - {error.get('detail')}")

Implement Retry Logic

For transient errors (429, 500, 503), implement exponential backoff:
import time
import requests

def make_request_with_retry(url, headers, data, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, headers=headers, json=data)

            if response.status_code == 200:
                return response.json()

            if response.status_code in [429, 500, 503]:
                # Exponential backoff: 1s, 2s, 4s
                wait_time = 2 ** attempt
                print(f"Retrying in {wait_time}s...")
                time.sleep(wait_time)
                continue

            # Don't retry client errors
            response.raise_for_status()

        except requests.exceptions.RequestException as e:
            if attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)

    raise Exception("Max retries exceeded")

Validate Input Before Sending

Catch errors early by validating input:
def validate_research_request(description):
    if not description or not description.strip():
        raise ValueError("Description cannot be empty")

    # Include as much detail as possible for best results
    if len(description) < 10:
        print("Warning: Short descriptions may yield less accurate results")

Log Errors for Debugging

Always log error details:
import logging

try:
    response = make_api_request(...)
except Exception as e:
    logging.error(f"API request failed: {e}", exc_info=True)
    # Handle error gracefully

Common Error Scenarios

Invalid API Key

curl -X POST https://api.happenstance.ai/v1/research \
  -H "Authorization: Bearer invalid_key" \
  -H "Content-Type: application/json" \
  -d '{"description": "John Smith, CEO at Acme Corp"}'

# Response: 401
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid API key",
  "instance": "/v1/research"
}
Fix: Use a valid API key from your account settings.

Empty Description

curl -X POST https://api.happenstance.ai/v1/research \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description": ""}'

# Response: 400
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "Description must not be empty",
  "instance": "/v1/research"
}
Fix: Provide a non-empty description with details about the person.

Research Not Found

curl -X GET https://api.happenstance.ai/v1/research/invalid-id \
  -H "Authorization: Bearer YOUR_KEY"

# Response: 404
{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "Research request not found",
  "instance": "/v1/research/invalid-id"
}
Fix: Check that the research ID is correct and belongs to your account.

Insufficient Credits

curl -X POST https://api.happenstance.ai/v1/search \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "engineers at Google"}'

# Response: 402
{
  "type": "about:blank",
  "title": "Payment Required",
  "status": 402,
  "detail": "Insufficient credits. You have 0 credits. This operation requires 2 credit(s).",
  "instance": "/v1/search"
}
Fix: Purchase more credits from your Settings page.

Empty Search Results

curl -X POST https://api.happenstance.ai/v1/search \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "engineers at Google", "include_my_connections": true}'

# Response: 200 (but with empty results)
{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "status": "COMPLETED",
  "results": []
}
Cause: You set include_my_connections or include_friends_connections to true, but you haven’t uploaded any connections to search across. Fix: Upload your LinkedIn connections at happenstance.ai before searching. Alternatively, search within specific groups by providing group_ids.

Need Help?