https://app.raisegate.com. Version: v1. Every path starts with /api/v1. JSON bodies, UTF-8. Live spec: GET /api/v1/openapi (no authentication).
IDs and timestamps
- All resource IDs are UUIDs. Malformed IDs return
400 validation_error. Unknown IDs, and IDs belonging to another organisation, return404 not_found. - Timestamps are ISO 8601 in UTC, as stored (for example
2026-09-17T21:24:36.654275+00:00). - Date filters (
since,until,updatedAfter) accept a date (2026-09-15) or a full timestamp. Foruntil, a bare date includes that whole UTC day; a timestamp is an exclusive upper bound.sincemust be earlier thanuntil.
Pagination
Every list endpoint is newest-first and cursor-paginated.limit: 1-100, default 25. Values above 100 are clamped to 100; non-numeric values return400.- The response carries
nextCursor; pass it back ascursorfor the next page.nextCursor: nullmeans there are no more results. - Cursors are opaque and strictly validated. Tampered or malformed cursors return
400 invalid_cursor. - Ordering is by creation time with the row ID as a tie-breaker, so paging never skips or repeats rows, even when rows share a timestamp.
Response views
List endpoints return a compact view by default; single-resourceGETs return the full view. Either can be requested explicitly:
view value returns 400 validation_error.
Measured sizes for 25 items:
Fuzzy entity lookup
Endpoints that filter by tracked company accept either an exact ID or a natural name:
Fuzzy lookup matches company and founder names and tolerates case, spacing, punctuation, joined words, legal suffixes and small typos. These variants all resolve to the same company, whether it is stored as “Anomaly”, “AnomalyBio”, “Anomaly Bio” or “Anomaly Biosciences, Inc.”:
sourceQuery=Suraj Prasd finds Suraj Prasad’s company). The response reports what matched:
entityResolution on /signals and /alerts.)
Two different companies that share a prefix (“Anomaly Bio” and “Anomaly Robotics”) are reported as ambiguous. Do not guess. Show the candidates to the user.
Sector filters
/tracker, /signals, /alerts and /leads accept classification (aliases sector, sectors) with natural wording, up to four comma-separated terms:
classificationResolution.
If the classifier is unavailable, matching falls back to text matching against stored category paths and degradedToTextMatching is true. If nothing matches, the result is an empty list, not an error.
Broad terms work best: biotech, robotics, fintech, climate tech, developer tools, healthcare, mlops, humanoids. A term containing a generic word can widen the match. humanoid robots behaves like robotics; use humanoids for humanoid companies only.
Idempotent creation
POST /api/v1/tracker accepts an Idempotency-Key header (8-200 printable ASCII characters, no spaces). Send a unique key per logical create so network retries are safe. Keys are remembered for 24 hours.
Independently of idempotency, submitting a company that is already tracked (same website, company LinkedIn or founder LinkedIn) reuses and updates the existing entity and returns
200 with existingEntity: true.
On MCP, add_company accepts an optional idempotencyKey. Without one, the server derives a key from the arguments, so an identical retried call returns the first result.
Rate limits
Limits apply per API key in fixed windows. Every authenticated request counts, including ones rejected later.
The hourly caps exist because those calls start paid scraping, enrichment and model work.
Retry-After seconds before retrying. Counters live in the tracker’s Redis; if Redis is unavailable the API keeps serving rather than blocking clients. Checking limits adds roughly 50-150 ms per request.
Errors
Every error uses the same envelope;details is present only when useful.
path: reason, so a client can fix everything in one round trip. Full table: Error reference.