Getting started with the API
Push your first feedback through the API in five minutes.
The BAI Analytics API does one job well: it moves feedback between your systems and your Feedback Groups. You push feedback in, the platform analyses it exactly as if it had arrived through a survey or upload, and you read the results back (or let a webhook tell you when they're ready).
Everything runs over HTTPS against the public ingestion host:
https://boundaryai-ingest-279197672085.europe-west9.run.appUse this host, not the dashboard's address. The dashboard host (app.*) serves the web application and answers every /api/... path with an HTML page and HTTP 200, which a generated client will happily parse as a success body. The published API reference carries the same host on every operation.
This walkthrough goes from nothing to analysed feedback. It uses the recommended vocabulary (feedback_group / source / field); see Concepts & naming for how that maps to what you see in the app.
Step 1: Create an API key
In the dashboard, open Integrations, go to Developer tools → API Keys (admin-only), and create a key. Pick a permission scope and copy the secret: it looks like inpk_live_... and is shown once.
Pass it on every call:
Authorization: Bearer inpk_live_...Verify it works:
curl https://boundaryai-ingest-279197672085.europe-west9.run.app/api/input/me \
-H "Authorization: Bearer $BAI_API_KEY"GET /me returns your key's permissions, the organisation it belongs to (org_name), your effective rate limits, the organisation's usage status, and the webhook events you can subscribe to. Details in Authentication & API keys.
Step 2: Create a feedback group and a source
A feedback group is the project container; a source is one stream of feedback inside it, with typed fields. Creating a feedback group needs an all key; creating and publishing sources needs create or all. If your group already exists, skip the first call and use its id.
curl -X POST https://boundaryai-ingest-279197672085.europe-west9.run.app/api/input/feedback_groups/create \
-H "Authorization: Bearer $BAI_API_KEY" -H "Content-Type: application/json" \
-d '{"name": "Customer Support EU"}'
curl -X POST https://boundaryai-ingest-279197672085.europe-west9.run.app/api/input/sources/create \
-H "Authorization: Bearer $BAI_API_KEY" -H "Content-Type: application/json" \
-d '{
"feedback_group_id": "1842",
"source_title": "Support tickets (CRM sync)",
"feedback_type": "support_ticket",
"fields": [
{"field_title": "What was the issue?", "field_type": "DEPTH_TEXT"},
{"field_title": "How likely are you to recommend us?", "field_type": "NPS"}
]
}'Sources are created in draft mode. Publish to start pushing:
Step 3: Push feedback
Items can be bare strings or structured objects. Three fields are worth using from day one:
external_id: your stable ID for the item. A retried push with anexternal_idthe field already holds is skipped rather than written twice; the response reports it underskipped_duplicates.occurred_at: when the feedback actually happened. It back-dates the item so time-tracked groups put it in the right period.Idempotency-Keyheader: makes the whole request safe to retry for 24 hours.
For backfills, use POST /feedback/push/bulk (many fields in one call; asynchronous by default, with a synchronous mode for small batches) or POST /feedback/upload with a CSV/XLSX file. See Pushing feedback.
Step 4: Read the analysis (or let a webhook tell you)
Analysis runs automatically after content lands. Read it back:
You get the sentiment distribution, themes, and Custom Monitoring matches. Rather than polling, subscribe to the analysis.completed event; see Webhooks.
Conventions to know
Success responses: today a 2xx response carries the payload directly, as shown in every example. Each 2xx also carries
DeprecationandSunsetheaders: they announce that, after the sunset date, success payloads will be wrapped as{"data": {...}}, exactly as the schemas in the reference already declare. They do not deprecate any endpoint. Reading the payload fromdatawhen that key is present, and from the root otherwise, keeps a client correct on both sides of the switch.Error envelope: failures return
{"error": {"code": "...", "message": "..."}}(plus an optionaldetailsobject) with a stable machine-readablecode.Rate limits: 60 requests/minute per key and 300/minute per organisation by default, on fixed 60-second windows; 429 responses carry a
Retry-Afterheader. Your key's exact limits are inGET /me.Pagination:
GET /feedbackis cursor-based (pass backnext_cursoruntilhas_moreis false);GET /sources/listtakeslimit(default 50, max 200) andoffsetand echoes apaginationobject.Test keys:
inpk_test_...keys behave identically but are meant for staging integrations; keep them out of production traffic.
Anything you push participates fully in the product: group monitors with auto-coverage watch API sources automatically (Custom Monitoring), and API data lands in Grouped Themes, Evolution periods, and reports like any other source.
Going deeper
Pushing feedback: bulk backfills, file ingest, deduplication, back-dating, erasure.
Sending invites (email API): trigger personalized survey invites from your own workflow.
Webhooks: act on events instead of polling.
Connect AI assistants (MCP): let an assistant query the results.
What's deliberately not in the API
Some things are dashboard-only on purpose, so if you're hunting for an endpoint that doesn't exist, this is probably why:
Survey and template building: what respondents and invitees see is designed, previewed, and reviewed in the platform; the API triggers it but can't rewrite it. A leaked key can never change what your customers receive.
Webhook subscription management: creating subscriptions and reading signing secrets happens in the dashboard, so an API key can't redirect your event stream to a new URL.
Email sending configuration: sender domains and sending tiers are organisation settings (Settings); the API sends through them but can't alter them.
Members and organisation settings: admin actions stay with admins.
If your use case genuinely needs one of these programmatically, tell us at dev@boundary-ai.com; we'd rather hear the case than have you build around it.
Last updated