BTIG Auto-Upload Agent
Automated upload of BTIG files to Sable using the User API Key system.
Authentication
Retrieve API Key
mcpammer_secrets_get name="SABLE_API_KEY_DANIEL" environment="dev" path="/"
Key format: sk_a5b6aac152e01d55066c0a1807eb4f81
Use in Requests
-H "x-api-key: $SABLE_API_KEY"
File Locations
| Directory | Purpose |
|---|---|
~/Downloads/BTIG/Ready To Upload/ | Files ready for upload |
~/Downloads/BTIG/Archive/ | Successfully uploaded |
~/Downloads/BTIG/Failed/ | Failed uploads (for retry) |
API Endpoint
Endpoint: POST https://sable.aicholdings.com/api/storage/upload
Form Fields:
| Field | Required | Description |
|---|---|---|
file | Yes | The CSV file |
org_id | Yes | 00000000-0000-0000-0000-000000000001 |
file_type | No | pnl or performance |
Example:
curl -X POST "https://sable.aicholdings.com/api/storage/upload" \
-H "x-api-key: $SABLE_API_KEY" \
-F "file=@/path/to/file.csv" \
-F "org_id=00000000-0000-0000-0000-000000000001"
Upload Script
import os
import shutil
import requests
API_KEY = os.environ.get("SABLE_API_KEY")
ORG_ID = "00000000-0000-0000-0000-000000000001"
UPLOAD_URL = "https://sable.aicholdings.com/api/storage/upload"
READY_DIR = os.path.expanduser("~/Downloads/BTIG/Ready To Upload")
ARCHIVE_DIR = os.path.expanduser("~/Downloads/BTIG/Archive")
FAILED_DIR = os.path.expanduser("~/Downloads/BTIG/Failed")
def upload_file(filepath):
filename = os.path.basename(filepath)
with open(filepath, "rb") as f:
response = requests.post(
UPLOAD_URL,
headers={"x-api-key": API_KEY},
files={"file": (filename, f, "text/csv")},
data={"org_id": ORG_ID}
)
return response.status_code == 200
def process_all():
for filename in os.listdir(READY_DIR):
if not filename.endswith(".csv"):
continue
filepath = os.path.join(READY_DIR, filename)
if upload_file(filepath):
shutil.move(filepath, os.path.join(ARCHIVE_DIR, filename))
print(f"Uploaded: {filename}")
else:
shutil.move(filepath, os.path.join(FAILED_DIR, filename))
print(f"Failed: {filename}")
if __name__ == "__main__":
process_all()
Error Handling
| Status | Error | Action |
|---|---|---|
| 401 | Invalid API key | Check/rotate key |
| 403 | Forbidden | Check org_id, permissions |
| 413 | File too large | Split file |
| 500 | Server error | Retry with backoff |
Verification
After upload:
- Go to Sable → Admin → File Bucket
- Check for new files with status "uploaded"
- Watch for processing to complete
Or via API:
curl "https://sable.aicholdings.com/api/storage/files?org_id=$ORG_ID" \
-H "x-api-key: $SABLE_API_KEY"