Happily.ai Get an API key

Run a performance review cycle

Submit manager reviews programmatically and reuse review templates across teams. This recipe covers performance "boosts" and presets.

Submit performance boosts

POST /api/v1/performance-boosts

A boost is a manager's review of a direct report. Send a single object or an array of up to 200. Each is processed independently, so the response is an array of per-item results.

Rules

  • reviewer_email must be the direct manager of employee_email.
  • Both people must belong to your company.
  • supporting_examples is required for goal performance and culture contribution.
  • A member can't be reviewed again until their review cycle resets.

Ratings

Section rating values
goal_performance exceeded_goals, met_goals, partially_met_goals, did_not_meet_goals
culture_contribution significantly, consistently, somewhat, rarely

Request

{
  "employee_email": "jordan@acme.com",
  "reviewer_email": "lee@acme.com",
  "review_date": "2026-06-01",
  "assessment_data": {
    "goal_performance": {
      "rating": "met_goals",
      "supporting_examples": "Hit all three OKRs and unblocked the launch."
    },
    "culture_contribution": {
      "rating": "consistently",
      "supporting_examples": "Mentored two teammates and ran the design crit."
    },
    "future_development": {
      "goals_targets_outcomes": "Lead the mobile redesign next quarter.",
      "skill_recommendations": "Stakeholder management"
    }
  }
}

future_development is optional.

Make the call

curl -X POST "https://api.happily.ai/prod/api/v1/performance-boosts" \
  -H "x-api-key: $HAPPILY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[{
    "employee_email": "jordan@acme.com",
    "reviewer_email": "lee@acme.com",
    "review_date": "2026-06-01",
    "assessment_data": {
      "goal_performance": { "rating": "met_goals", "supporting_examples": "Hit all three OKRs." },
      "culture_contribution": { "rating": "consistently", "supporting_examples": "Mentored two teammates." }
    }
  }]'
const boosts = [
  {
    employee_email: "jordan@acme.com",
    reviewer_email: "lee@acme.com",
    review_date: "2026-06-01",
    assessment_data: {
      goal_performance: { rating: "met_goals", supporting_examples: "Hit all three OKRs." },
      culture_contribution: { rating: "consistently", supporting_examples: "Mentored two teammates." },
    },
  },
];

const res = await fetch("https://api.happily.ai/prod/api/v1/performance-boosts", {
  method: "POST",
  headers: { "x-api-key": process.env.HAPPILY_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify(boosts),
});
const { body: results } = await res.json();
for (const r of results) {
  if (r.success) console.log("OK", r.employee_email);
  else console.warn("FAILED", r.error_code, r.error);
}
import os, requests

boosts = [{
    "employee_email": "jordan@acme.com",
    "reviewer_email": "lee@acme.com",
    "review_date": "2026-06-01",
    "assessment_data": {
        "goal_performance": {"rating": "met_goals", "supporting_examples": "Hit all three OKRs."},
        "culture_contribution": {"rating": "consistently", "supporting_examples": "Mentored two teammates."},
    },
}]

res = requests.post(
    "https://api.happily.ai/prod/api/v1/performance-boosts",
    headers={"x-api-key": os.environ["HAPPILY_API_KEY"]},
    json=boosts,
)
for r in res.json()["body"]:
    print("OK" if r.get("success") else f"FAILED {r.get('error_code')}", r)

Response

{
  "statusCode": 200,
  "body": [
    { "success": true, "employee_email": "jordan@acme.com", "reviewer_email": "lee@acme.com", "review_date": "2026-06-01" }
  ]
}
Important

A 200 does not mean every boost succeeded. Each item in body is independent. Check success, and on failure read error_code and error. See the error codes.

Save a review preset

POST /api/v1/performance-preset

A preset is a reusable review template assigned to teams or members. Provide either teams (internal team IDs, max 50) or members (emails, max 50).

curl -X POST "https://api.happily.ai/prod/api/v1/performance-preset" \
  -H "x-api-key: $HAPPILY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q3 Engineering Review",
    "goals_feedback": "Reflect on your top goal this quarter.",
    "culture_contribution": "How did you live our values?",
    "next_review": "2026-09-01",
    "teams": ["t123456789"]
  }'
import os, requests

res = requests.post(
    "https://api.happily.ai/prod/api/v1/performance-preset",
    headers={"x-api-key": os.environ["HAPPILY_API_KEY"]},
    json={
        "name": "Q3 Engineering Review",
        "goals_feedback": "Reflect on your top goal this quarter.",
        "culture_contribution": "How did you live our values?",
        "next_review": "2026-09-01",
        "teams": ["t123456789"],
    },
)
print(res.json()["data"]["_id"])
Note

Each team or member belongs to a single preset. When you assign a team or member to a new preset, they are removed from any preset that previously covered them.

Read existing feedback

GET /1/performance_feedback?email=jordan@acme.com&reviewer_email=lee@acme.com

Provide email (the employee), reviewer_email (the reviewer), or both. The response contains a feedback array with score and comment, plus a pagination object.

Next steps