Pull survey analytics
Export your survey questions and the responses members submit, then load them into your warehouse or BI tool.
List questions
GET /questions
Returns the questions available to your company (your custom questions plus shared "main" questions). Filter by type, skill, or dimension.
| Filter | Values |
|---|---|
type |
Question type, for example Multiple Choice. |
skill |
Critical Thinking, Empathy, Initiative Making, Leadership, Self Awareness, Optimism. |
dimension |
A question category/dimension name. |
curl "https://api.happily.ai/prod/1/questions?skill=Empathy&limit=250" \
-H "x-api-key: $HAPPILY_API_KEY"
{
"statusCode": 200,
"message": "success",
"questions": [
{
"question_id": "q_abc123",
"question_text": "How supported did you feel this week?",
"type": "Multiple Choice",
"options": ["Not at all", "A little", "Mostly", "Completely"],
"skill": "Empathy",
"dimension": "Belonging"
}
],
"pagination": { "currentPage": 1, "totalPages": 1, "totalItems": 1, "pageSize": 250 }
}
List responses
GET /responses
Filter by email, question_id, or both (at least one is required). Bound by date with date_from and date_to (YYYY-MM-DD).
curl "https://api.happily.ai/prod/1/responses?question_id=q_abc123&date_from=2026-01-01&date_to=2026-06-30&limit=250" \
-H "x-api-key: $HAPPILY_API_KEY"
{
"statusCode": 200,
"message": "success",
"responses": [
{
"email": "jordan@acme.com",
"question_id": "q_abc123",
"question_text": "How supported did you feel this week?",
"answer": "Mostly",
"date": "2026-06-03"
}
],
"pagination": { "currentPage": 1, "totalPages": 1, "totalItems": 1, "pageSize": 250 }
}
Export everything to a CSV
This script pages through every response for a question and writes a CSV, pacing within the pagination limits.
import os, csv, requests
API = "https://api.happily.ai/prod/1"
HEADERS = {"x-api-key": os.environ["HAPPILY_API_KEY"]}
def responses_for_question(question_id, date_from, date_to):
page = 1
while True:
res = requests.get(f"{API}/responses", headers=HEADERS, params={
"question_id": question_id,
"date_from": date_from,
"date_to": date_to,
"page": page,
"limit": 250,
})
body = res.json()
yield from body.get("responses", [])
if page >= body["pagination"]["totalPages"]:
break
page += 1
with open("responses.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["email", "question_id", "question_text", "answer", "date"])
writer.writeheader()
for row in responses_for_question("q_abc123", "2026-01-01", "2026-06-30"):
writer.writerow(row)
const API = "https://api.happily.ai/prod/1";
const headers = { "x-api-key": process.env.HAPPILY_API_KEY };
async function* responsesForQuestion(questionId, dateFrom, dateTo) {
let page = 1;
while (true) {
const url = new URL(`${API}/responses`);
url.search = new URLSearchParams({ question_id: questionId, date_from: dateFrom, date_to: dateTo, page, limit: 250 });
const body = await (await fetch(url, { headers })).json();
for (const row of body.responses ?? []) yield row;
if (page >= body.pagination.totalPages) break;
page++;
}
}
for await (const row of responsesForQuestion("q_abc123", "2026-01-01", "2026-06-30")) {
console.log(row.email, row.answer, row.date);
}
Use limit=250 for exports and schedule a nightly job to incrementally pull the previous day's responses with date_from/date_to.
Member engagement profiles
For richer analytics on a single person, fetch their engagement profile:
GET /api/v1/users/{email}/profile
It returns impact_rating, engagement_health_score (0–100), an engagement_health_status (Novice, Intermediate, Advanced, Elite), and optional personal_context. Set include_personal_context=false to omit the context block, or context_limit (1–50) to cap each list.
Get an API key