API

Sky AI External API Documentation

TL;DR: https://dev-api.app.usesky.ai/external-api/docs (Swagger)

Overview

The Sky AI External API provides programmatic access to Sky AI's document processing and management platform. This API enables you to create cases, upload documents, manage document categories, and integrate Sky AI's powerful document processing capabilities into your own applications.


The API is built on REST principles with predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes and authentication.


Base URL

Production: https://api.app.usesky.ai/external-api/

Development: https://dev-api.app.usesky.ai/external-api/


Authentication

The Sky AI External API uses API keys to authenticate requests. You can create and manage your API keys from the Sky AI dashboard under Settings > Developers > API Key.


Creating an API Key

  1. Log in to your Sky AI account
  2. Navigate to Settings > Developers

  3. Click Create API Key
  4. Enter a name for your API key (e.g., "Production Server")
  5. Click Create

  6. Copy and securely store your API key - you won't be able to see it again

Using Your API Key

Include your API key in every request using one of two methods:


Method 1: Authorization Header (Recommended)

Authorization: Bearer YOUR_API_KEY

Method 2: X-API-Key Header

X-API-Key: YOUR_API_KEY

Security Best Practices

  • Never share your API keys publicly or commit them to version control
  • Store API keys securely using environment variables or a secrets manager
  • Rotate API keys periodically
  • Use different API keys for different environments (development, staging, production)
  • Revoke API keys immediately if they are compromised

Rate Limiting

The API implements rate limiting to ensure fair usage and system stability:


  • Rate Limit: 100 requests per minute per organization
  • Rate limits are tracked using Redis and are organization-specific
  • When you exceed the rate limit, you'll receive a 429 Too Many Requests  response

Rate limit information is included in response headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699564800

Error Handling

The API uses conventional HTTP response codes to indicate the success or failure of requests:


  • 2xx - Success
  • 4xx - Client errors (invalid request, authentication failure, etc.)
  • 5xx - Server errors

Error Response Format

{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request"
}

Common Error Codes

Status Code Description
400 Bad Request - Invalid request parameters
401 Unauthorized - Invalid or missing API key
404 Not Found - Resource doesn't exist
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Something went wrong on our end

API Resources

Cases

Cases (also called "Folders" or "Projects" internally) are containers for organizing documents. Each case represents a distinct matter, claim, or project that you're working on.


Create a Case

Creates a new case in your organization.


Endpoint: POST /cases


Request Body:


Field Type Required Description
name string Yes Name of the case
claimNumber string Yes Unique claim or case number
dateOfBirth string Yes Date of birth (ISO 8601 format or string)
dateOfLoss string No Date of loss/incident (ISO 8601 format or string)

Example Request:


curl -X POST https://api.app.usesky.ai/external-api/cases \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Smith vs. Johnson",
    "claimNumber": "CLM-2024-001",
    "dateOfBirth": "1985-03-15",
    "dateOfLoss": "2024-01-10"
  }'

Response: 201 Created


"case_abc123def456"

The response returns the unique case ID as a string.


JavaScript Example:


const response = await fetch('https://api.app.usesky.ai/external-api/cases', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Smith vs. Johnson',
    claimNumber: 'CLM-2024-001',
    dateOfBirth: '1985-03-15',
    dateOfLoss: '2024-01-10'
  })
});

const caseId = await response.json();
console.log('Created case:', caseId);

Python Example:


import requests

response = requests.post(
    'https://api.app.usesky.ai/external-api/cases',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Smith vs. Johnson',
        'claimNumber': 'CLM-2024-001',
        'dateOfBirth': '1985-03-15',
        'dateOfLoss': '2024-01-10'
    }
)

case_id = response.json()
print(f'Created case: {case_id}')

List Cases

Retrieves a paginated list of all cases in your organization.


Endpoint: GET /cases


Query Parameters:


Parameter Type Default Description
page integer 1 Page number for pagination
limit integer 20 Number of items per page (min: 10, max: 100)

Example Request:


curl -X GET "https://api.app.usesky.ai/external-api/cases?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response: 200 OK


{
  "folders": [
    {
      "id": "case_abc123def456",
      "name": "Smith vs. Johnson",
      "dateOfLoss": "2024-01-10T00:00:00.000Z",
      "dateOfBirth": "1985-03-15T00:00:00.000Z",
      "contextIrrelevant": false,
      "lastPipelineUpdatedAt": "2024-11-12T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

JavaScript Example:


const response = await fetch(
  'https://api.app.usesky.ai/external-api/cases?page=1&limit=20',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);

const data = await response.json();
console.log(`Found ${data.pagination.total} cases`);
data.folders.forEach(case => {
  console.log(`- ${case.name} (${case.id})`);
});

Python Example:


import requests

response = requests.get(
    'https://api.app.usesky.ai/external-api/cases',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={'page': 1, 'limit': 20}
)

data = response.json()
print(f"Found {data['pagination']['total']} cases")
for case in data['folders']:
    print(f"- {case['name']} ({case['id']})")

Get Case by ID

Retrieves detailed information about a specific case.


Endpoint: GET /cases/{id}


Path Parameters:


Parameter Type Description
id string The unique case ID

Example Request:


curl -X GET https://api.app.usesky.ai/external-api/cases/case_abc123def456 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response: 200 OK


{
  "id": "case_abc123def456",
  "name": "Smith vs. Johnson",
  "type": "ROOT",
  "organizationId": "org_xyz789",
  "authorId": "user_123",
  "claimNumber": "CLM-2024-001",
  "dateOfBirth": "1985-03-15T00:00:00.000Z",
  "dateOfLoss": "2024-01-10T00:00:00.000Z",
  "createdAt": "2024-11-01T09:00:00.000Z",
  "updatedAt": "2024-11-12T10:30:00.000Z"
}

Archive a Case

Archives a case and all its associated documents. Archived cases are moved to a separate storage area and are no longer actively processed.


Endpoint: PATCH /cases/{id}/archive


Path Parameters:


Parameter Type Description
id string The unique case ID

Example Request:


curl -X PATCH https://api.app.usesky.ai/external-api/cases/case_abc123def456/archive \
  -H "Authorization: Bearer YOUR_API_KEY"

Response: 200 OK


No response body is returned on success.


JavaScript Example:


const response = await fetch(
  'https://api.app.usesky.ai/external-api/cases/case_abc123def456/archive',
  {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);

if (response.ok) {
  console.log('Case archived successfully');
}

Python Example:


import requests

response = requests.patch(
    'https://api.app.usesky.ai/external-api/cases/case_abc123def456/archive',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

if response.ok:
    print('Case archived successfully')

Document Categories

Document categories help organize and classify documents within your cases. Categories are organization-wide templates that define how documents should be classified, named, and processed.


List Categories

Retrieves all document categories for your organization.


Endpoint: GET /categories


Example Request:


curl -X GET https://api.app.usesky.ai/external-api/categories \
  -H "Authorization: Bearer YOUR_API_KEY"

Response: 200 OK


[
  {
    "id": 1,
    "name": "Medical Records",
    "color": "#3B82F6",
    "definition": "All medical documentation including doctor's notes, test results, and treatment records",
    "namingConvention": "MED-[Date]-[Type]",
    "namingExample": "MED-2024-01-15-Lab-Results",
    "length": "Varies, typically 5-50 pages",
    "keyTopics": "Diagnosis, treatment, medications, test results",
    "expectedContent": "Clinical notes, lab results, imaging reports, prescriptions",
    "recognitionTips": "Look for medical terminology, doctor signatures, hospital letterhead",
    "isFallback": false
  },
  {
    "id": 2,
    "name": "Legal Documents",
    "color": "#8B5CF6",
    "definition": "Legal correspondence, contracts, and court documents",
    "namingConvention": "LEGAL-[Date]-[Type]",
    "namingExample": "LEGAL-2024-02-01-Contract",
    "length": "Varies, typically 2-100 pages",
    "keyTopics": "Agreements, litigation, compliance",
    "expectedContent": "Contracts, pleadings, motions, correspondence",
    "recognitionTips": "Legal terminology, signatures, notarization",
    "isFallback": false
  }
]

JavaScript Example:


const response = await fetch(
  'https://api.app.usesky.ai/external-api/categories',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);

const categories = await response.json();
categories.forEach(category => {
  console.log(`${category.name} (${category.color})`);
});

Python Example:


import requests

response = requests.get(
    'https://api.app.usesky.ai/external-api/categories',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

categories = response.json()
for category in categories:
    print(f"{category['name']} ({category['color']})")

Create a Category

Creates a new document category template for your organization.


Endpoint: POST /categories


Request Body:


Field Type Required Description
name string Yes Category name
color string Yes Hex color code (e.g., "#3B82F6")
definition string Yes Description of what documents belong in this category
namingConvention string Yes Convention for naming documents in this category
namingExample string Yes Example of the naming convention
length string Yes Expected length/page count of documents
keyTopics string Yes Main topics covered in this category
expectedContent string Yes Types of content expected in documents
recognitionTips string Yes Tips for identifying documents in this category
isFallback boolean Yes Whether this is a fallback category for unclassified documents

Example Request:


curl -X POST https://api.app.usesky.ai/external-api/categories \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Financial Records",
    "color": "#10B981",
    "definition": "Financial statements, invoices, and payment records",
    "namingConvention": "FIN-[Date]-[Type]",
    "namingExample": "FIN-2024-03-01-Invoice",
    "length": "Typically 1-20 pages",
    "keyTopics": "Payments, expenses, revenue, taxes",
    "expectedContent": "Invoices, receipts, bank statements, tax documents",
    "recognitionTips": "Look for dollar amounts, account numbers, payment terms",
    "isFallback": false
  }'

Response: 201 Created


{
  "id": 3,
  "name": "Financial Records",
  "color": "#10B981",
  "definition": "Financial statements, invoices, and payment records",
  "namingConvention": "FIN-[Date]-[Type]",
  "namingExample": "FIN-2024-03-01-Invoice",
  "length": "Typically 1-20 pages",
  "keyTopics": "Payments, expenses, revenue, taxes",
  "expectedContent": "Invoices, receipts, bank statements, tax documents",
  "recognitionTips": "Look for dollar amounts, account numbers, payment terms",
  "isFallback": false
}

JavaScript Example:


const response = await fetch(
  'https://api.app.usesky.ai/external-api/categories',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'Financial Records',
      color: '#10B981',
      definition: 'Financial statements, invoices, and payment records',
      namingConvention: 'FIN-[Date]-[Type]',
      namingExample: 'FIN-2024-03-01-Invoice',
      length: 'Typically 1-20 pages',
      keyTopics: 'Payments, expenses, revenue, taxes',
      expectedContent: 'Invoices, receipts, bank statements, tax documents',
      recognitionTips: 'Look for dollar amounts, account numbers, payment terms',
      isFallback: false
    })
  }
);

const category = await response.json();
console.log('Created category:', category.id);

Python Example:


import requests

response = requests.post(
    'https://api.app.usesky.ai/external-api/categories',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Financial Records',
        'color': '#10B981',
        'definition': 'Financial statements, invoices, and payment records',
        'namingConvention': 'FIN-[Date]-[Type]',
        'namingExample': 'FIN-2024-03-01-Invoice',
        'length': 'Typically 1-20 pages',
        'keyTopics': 'Payments, expenses, revenue, taxes',
        'expectedContent': 'Invoices, receipts, bank statements, tax documents',
        'recognitionTips': 'Look for dollar amounts, account numbers, payment terms',
        'isFallback': False
    }
)

category = response.json()
print(f"Created category: {category['id']}")

Update a Category

Updates an existing document category.


Endpoint: PUT /categories/{id}


Path Parameters:


Parameter Type Description
id number The category ID

Request Body:


All fields from the create request are supported. All fields are optional - only include the fields you want to update.


Example Request:


curl -X PUT https://api.app.usesky.ai/external-api/categories/3 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Financial & Accounting Records",
    "color": "#059669"
  }'

Response: 200 OK


{
  "id": 3,
  "name": "Financial & Accounting Records",
  "color": "#059669",
  "definition": "Financial statements, invoices, and payment records",
  "namingConvention": "FIN-[Date]-[Type]",
  "namingExample": "FIN-2024-03-01-Invoice",
  "length": "Typically 1-20 pages",
  "keyTopics": "Payments, expenses, revenue, taxes",
  "expectedContent": "Invoices, receipts, bank statements, tax documents",
  "recognitionTips": "Look for dollar amounts, account numbers, payment terms",
  "isFallback": false
}

Delete a Category

Deletes a document category from your organization.


Endpoint: DELETE /categories/{id}


Path Parameters:


Parameter Type Description
id number The category ID

Example Request:


curl -X DELETE https://api.app.usesky.ai/external-api/categories/3 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response: 200 OK


Returns the updated list of all remaining categories (same format as List Categories).


Document Upload

Upload documents to a specific case for processing. The API accepts PDF files and will automatically process them through Sky AI's document processing pipeline.


Upload a Document

Uploads a document file to a specific case.


Endpoint: POST /upload/{caseId}


Path Parameters:


Parameter Type Description
caseId string The case ID to upload the document to

Request Body:


This endpoint accepts multipart/form-data  with a file field.


Field Type Required Description
file file Yes The document file to upload (PDF format)

Example Request:


curl -X POST https://api.app.usesky.ai/external-api/upload/case_abc123def456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@/path/to/document.pdf"

Response: 201 Created


{
  "uploadId": "upload_xyz789abc123"
}

The response returns a unique upload ID that can be used to track the upload and processing status.


JavaScript Example (Browser):


const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const formData = new FormData();
formData.append('file', file);

const response = await fetch(
  'https://api.app.usesky.ai/external-api/upload/case_abc123def456',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    body: formData
  }
);

const result = await response.json();
console.log('Upload ID:', result.uploadId);

JavaScript Example (Node.js):


const fs = require('fs');
const FormData = require('form-data');
const fetch = require('node-fetch');

const form = new FormData();
form.append('file', fs.createReadStream('/path/to/document.pdf'));

const response = await fetch(
  'https://api.app.usesky.ai/external-api/upload/case_abc123def456',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      ...form.getHeaders()
    },
    body: form
  }
);

const result = await response.json();
console.log('Upload ID:', result.uploadId);

Python Example:


import requests

with open('/path/to/document.pdf', 'rb') as file:
    response = requests.post(
        'https://api.app.usesky.ai/external-api/upload/case_abc123def456',
        headers={'Authorization': 'Bearer YOUR_API_KEY'},
        files={'file': file}
    )

result = response.json()
print(f"Upload ID: {result['uploadId']}")

Document Processing Pipeline

After uploading a document, Sky AI automatically processes it through a multi-stage pipeline:


  1. Preview Generation - Extracts document metadata
  2. Preprocessing - Splits document into pages and generates previews
  3. Content Extraction - Uses AI to extract text content from each page
  4. Continuation Analysis - Determines which pages belong together
  5. Summarization - Generates summaries for document sections
  6. Classification - Assigns documents to categories
  7. Context Generation - Creates chat-ready context for AI interactions

This processing happens asynchronously in the background. The time required depends on document size and complexity, typically ranging from a few seconds to several minutes for large documents.


Pagination

List endpoints support pagination using page  and limit  query parameters.


Parameters:

  • page  (integer, default: 1) - The page number to retrieve
  • limit  (integer, default: 20, min: 10, max: 100) - Number of items per page

Response Format:


{
  "folders": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

Pagination Metadata:

  • page  - Current page number
  • limit  - Items per page
  • total  - Total number of items
  • totalPages  - Total number of pages

Best Practices

Error Handling

Always implement proper error handling in your integration:


try {
  const response = await fetch('https://api.app.usesky.ai/external-api/cases', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(caseData)
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API Error: ${error.message}`);
  }

  const result = await response.json();
  return result;
} catch (error) {
  console.error('Failed to create case:', error);
  // Handle error appropriately
}

Retry Logic

Implement exponential backoff for retrying failed requests:


async function apiRequestWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        // Rate limited - wait and retry
        const waitTime = Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}

Webhook Integration (Coming Soon)

Webhook support for real-time notifications about document processing status is planned for a future release. This will allow you to receive notifications when:


  • Documents complete processing
  • Cases are updated
  • Processing errors occur

SDK Libraries

Official SDK libraries are planned for the following languages:


  • JavaScript/TypeScript (Node.js and Browser)
  • Python
  • C# / .NET
  • Java

Check the Sky AI Developer Portal for updates on SDK availability.


Support

If you encounter issues or have questions about the API:



Changelog

Version 1.0 (Current)

  • Initial release of External API
  • Case management endpoints
  • Document category management
  • Document upload functionality
  • API key authentication
  • Rate limiting (100 requests/minute)

Appendix

Supported File Formats

Currently, the API supports:

  • PDF (.pdf)

Support for additional formats (DOCX, images, etc.) is planned for future releases.


API Limits

  • Rate Limit: 100 requests per minute per organization
  • File Size: Maximum 100MB per upload
  • Page Count: Maximum 500 pages per document

Date Formats

The API accepts dates in the following formats:

  • ISO 8601: 2024-01-15T10:30:00Z
  • Date string: 2024-01-15
  • Human-readable: January 15, 2024

Dates are returned in ISO 8601 format in API responses.


Color Codes

Category colors should be specified as hex color codes:

  • Format: #RRGGBB
  • Example: #3B82F6  (blue)
  • Must include the #  prefix
  • Case insensitive

HTTP Headers

Request Headers:

  • Authorization: Bearer YOUR_API_KEY  - Authentication (required)
  • Content-Type: application/json  - For JSON request bodies
  • Content-Type: multipart/form-data  - For file uploads

Response Headers:

  • Content-Type: application/json  - All responses are JSON
  • X-RateLimit-Limit  - Rate limit maximum
  • X-RateLimit-Remaining  - Remaining requests in current window
  • X-RateLimit-Reset  - Unix timestamp when rate limit resets
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us