API Documentation
Integrate FinTrakker license alerts into your compliance workflow. RESTful JSON API with JWT authentication, webhook delivery, and CSV export.
Overview
The FinTrakker API provides programmatic access to license alert data, webhook management, and compliance exports. All API requests are made to the base URL:
https://firmhound.comThe API uses standard HTTP methods and returns JSON responses (except the CSV export endpoint). All timestamps are ISO 8601 format in UTC.
https://firmhound.com. For example, GET /alerts maps to https://firmhound.com/alerts.Authentication
Protected endpoints require a JSON Web Token (JWT) passed as a Bearer token in the Authorization header. Obtain your token by signing in at firmhound.com or via the POST /auth/login endpoint.
Request Header
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJ1c3JfNDQ4MTIwOSIsInByb2R1Y3RJZHMiOlsiZmludHJha2tlciJdLCJpYXQiOjE3NDQ5OTk5OTl9.example_signature
Getting a Token
curl -X POST https://firmhound.com/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "yourpassword",
"productId": "fintrakker"
}'
The response includes a token field. Tokens are valid for 30 days. Store tokens securely and never expose them in client-side code.
Rate Limits
API rate limits are applied per authenticated user. Unauthenticated requests (public endpoints like RSS) have their own limits.
| Plan | Rate Limit | Burst | Window |
|---|---|---|---|
| Starter | 100 requests/min | 200 | Rolling 60s |
| Professional | 1,000 requests/min | 2,000 | Rolling 60s |
| Enterprise | Unlimited | Negotiated | Custom SLA |
| Public (RSS, unauthenticated) | 60 requests/min | 120 | Rolling 60s |
Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When the limit is exceeded the API returns 429 Too Many Requests.
Endpoints
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| product_id | string | Optional | Filter by product. Use fintrakker for this product. |
| since | ISO date | Optional | Return alerts published after this date. Format: 2026-01-01T00:00:00Z |
| limit | integer | Optional | Number of results to return. Range: 1–100. Default: 20. |
| status | string | Optional | Filter by alert status. Values: active, expired, all. Default: active. |
Response
{
"alerts": [
{
"id": "alt_7f4a2c8e",
"product_id": "fintrakker",
"title": "TX Money Transmitter License — Renewal Due in 7 Days",
"description": "Your Texas MTL (TX-DOB-MT-2024-00481) expires Apr 26, 2026. Surety bond ($300,000) must be on file with TX DOB prior to submission.",
"source_url": "https://www.dob.texas.gov/licensing",
"published_at": "2026-04-19T07:17:00Z",
"severity": "critical",
"metadata": {
"state": "TX",
"license_type": "Money Transmitter",
"license_number": "TX-DOB-MT-2024-00481",
"nmls_id": "4481209",
"expires_at": "2026-04-26T00:00:00Z",
"days_until_expiry": 7
}
}
],
"total": 42,
"has_more": true
}
Code Examples
curl -X GET "https://firmhound.com/alerts?product_id=fintrakker&limit=20&status=active" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_JWT_TOKEN"}
params = {
"product_id": "fintrakker",
"limit": 20,
"status": "active",
"since": "2026-01-01T00:00:00Z"
}
resp = requests.get("https://firmhound.com/alerts", headers=headers, params=params)
data = resp.json()
for alert in data["alerts"]:
print(f"[{alert['severity'].upper()}] {alert['title']}")
const resp = await fetch(
'https://firmhound.com/alerts?product_id=fintrakker&limit=20',
{ headers: { Authorization: 'Bearer YOUR_JWT_TOKEN' } }
);
const { alerts, total, has_more } = await resp.json();
console.log(`Fetched ${alerts.length} of ${total} alerts`);
Returns text/csv with the same filtering options as GET /alerts. Useful for compliance documentation, board reports, and audit records.
Query Parameters
Same parameters as GET /alerts: product_id, since, limit, status.
Example
curl -X GET "https://firmhound.com/alerts/export?product_id=fintrakker&since=2026-01-01T00:00:00Z" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-o fintrakker-alerts-2026.csv
CSV columns: id, title, description, severity, state, license_type, license_number, published_at, source_url.
Returns all webhooks registered to your account. Webhooks are product-scoped.
curl -X GET https://firmhound.com/webhooks \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Response
{
"webhooks": [
{
"id": "wh_3c9e1a42",
"url": "https://hooks.yourapp.com/fintrakker",
"product_id": "fintrakker",
"events": ["alert.created"],
"created_at": "2026-01-15T12:00:00Z",
"active": true
}
]
}
Registers an HTTPS endpoint to receive alert events. Only HTTPS URLs are accepted. URLs pointing to private IP ranges are blocked for security.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Required | HTTPS endpoint URL. Must be publicly reachable. |
| product_id | string | Required | Product to receive events for. Use fintrakker. |
| events | string[] | Required | Array of event types. Currently supports alert.created. |
curl -X POST https://firmhound.com/webhooks \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.yourapp.com/fintrakker",
"product_id": "fintrakker",
"events": ["alert.created"]
}'
X-Firmhound-Signature header on all incoming requests. See the Integrations page for verification code samples.Deletes a webhook registration. No further events will be sent to the endpoint.
curl -X DELETE https://firmhound.com/webhooks/wh_3c9e1a42 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Returns 204 No Content on success.
Public RSS 2.0 feed of the 20 most recent alerts for a product. No authentication required. Compatible with any standard RSS reader.
# FinTrakker RSS feed URL
https://firmhound.com/feed/fintrakker
The feed returns standard RSS 2.0 XML with alert titles, descriptions, publication dates, source URLs, and severity metadata in the <item> elements.
SDKs
Official SDKs are in development. In the meantime, the API is straightforward to integrate using any HTTP client.