PerfCopilot

Write the review from the goals your team already set in 15Five

PerfCopilot reads the 15Five objectives and key results each person owned during the cycle you are reviewing, then drafts a performance review where every claim about goal progress comes from that synced goal data and is tagged with the source it came from, bias-checked before a manager sees it. The credential is a read-only API token you generate in your own 15Five account, and nothing is ever written back into 15Five.

Connect 15Five and draft a review → · read-only, no credit card, no seat minimum

✓ Objectives with their nested key results · ✓ Every goal claim tagged to its source · ✓ Bias-checked before you send

If your team already writes objectives in 15Five, those objectives are the clearest statement of what each person was asked to do this period. They are also the thing managers most often retype from memory at review time, which is where the vagueness starts. This page is about the alternative: reading them directly, one employee at a time, and keeping the review's sentences anchored to that record rather than to a manager's recollection of it.

What PerfCopilot reads from 15Five

One endpoint carries the whole sync. PerfCopilot asks 15Five for the objectives owned by a single person, reads the key results nested inside each one, and stops there.

GET /api/public/objectives/?owner=<one employee>&page_size=200

  from each objective    name, description, status,
                         start_date / end_date  (falling back to
                         created_at / due_date when those are absent)

  from each key result   id, name, status,
                         target_value  (or target)

The base URL defaults to https://my.15five.com/api/public and the response is read as a paged list, so a tenant on a different host is a configuration change rather than a code change. Three things follow from that shape, and each one matters at review time:

How a 15Five status becomes a review status

15Five and PerfCopilot do not use the same words for how a goal is going, so the sync maps one onto the other. The mapping is fixed and worth knowing before you read a draft:

Status in 15FiveStatus in PerfCopilot
achieved, completed, donecompleted
behind, at_riskat risk
needs_attention, off_track, missedoff track
on_track, or anything unrecognisedon track

Two deliberate choices sit in that table. needs_attention maps to off track rather than at risk, because in 15Five's own workflow it is the state asking for the most intervention, and rounding it down would flatter the review. And an unrecognised value reads as on track rather than failing the sync, which keeps a 15Five release from breaking a review cycle, at the cost of looking optimistic. If your team uses custom statuses, read a draft with that in mind.

PerfCopilot can also roll an objective's status up from its key results, computed at every read rather than cached: all key results completed reads as completed, any one off track makes the objective off track, any one at risk makes it at risk, and otherwise it is on track. That roll-up does not run on a 15Five objective. Every goal the sync writes is given an explicit status, taken from the mapping above and stored on the goal record, and an explicit status always wins over the roll-up. The roll-up is reachable only for goals a manager types into PerfCopilot by hand and leaves without a status of their own.

The consequence deserves saying plainly: because a missing status maps to on track, an objective that 15Five sends with no status at all is stored and shown as on track even when every key result under it is off track. That is the same optimism as the unrecognised-status row above, arriving from the other direction. If an objective's status reads kinder than its key results, the status came from 15Five, and the key results are the line to read.

Which objectives count toward the cycle you are reviewing

An objective counts for a review cycle when its period overlaps the cycle's period, inclusive at both ends. That is the rule, and it is more useful than a tidier one: a half-year objective that straddles the start of a quarter is part of what that quarter's review should discuss, so it is included rather than dropped for starting too early.

When 15Five supplies no dates at all, the first sync gives the goal a window of the day it arrived plus the next 90 days, and only on first creation. A later sync will not move those dates unless 15Five actually sends new ones. That is a small thing with a real consequence: a date that drifted on every sync would quietly move goals in and out of review periods behind the manager's back.

When you run Sync All for a cycle, every overlapping goal is also mirrored into that cycle's signal strip and stamped no later than the cycle's end date, rebuilt from scratch on each run. That is what lets you see the goal coverage a review will be written from before you generate anything.

What the draft actually does with an objective

The model that writes the review does not get a goals dashboard. It gets the objectives and key results for the cycle, as structured data, inside the block of available performance data:

[GOALS DATA]
[
  {
    "title":        "Cut onboarding time for new accounts",
    "description":  "Get a new account to first value without a call.",
    "period_start": "2026-07-01",
    "period_end":   "2026-09-30",
    "status":       "completed",
    "key_results": [
      { "title": "Median setup under 3 days", "target": "3",  "progress_percent": null, "status": "completed" },
      { "title": "Self-serve guide published", "target": null, "progress_percent": null, "status": "completed" }
    ]
  }
]

Two fields in there are easy to miss. The objective's description travels with it, so whatever your team typed into the description box is part of what the model reads, not just something a manager can look up later. And progress_percent is a real field on every key result, but the 15Five sync never fills it in: the sync reads each key result's id, name, status and target only, so it reaches the model as null unless someone has set a number on that key result inside PerfCopilot.

Four rules in the prompt decide what the draft may do with that block, and together they are the whole argument for connecting 15Five rather than summarising it by hand:

The practical difference is small in a sentence and large in a review conversation: a line about goal progress is marked as coming from the objectives the employee set in 15Five, and those objectives are sitting in the tool they already use, open to be read and argued with. Tying a particular sentence to a particular objective is still a question for the conversation, because the tag names the source and carries no objective's identity with it.

Goal attainment across the team, with the source named

Once goals are in, the cycle has an attainment view: how many objectives across the team or department sit in each of the four statuses, with a drill-down list giving the employee, the objective's title, its status, and the source it came from.

That last column is the honest part, and it is there on purpose. A goal synced from 15Five and a goal typed into PerfCopilot by a manager are not the same quality of evidence, and a calibration meeting that cannot tell them apart will treat a tidy record as a strong performance. Naming the source makes that visible rather than tidy. If calibration is where your ratings actually get decided, the calibration meeting guide is the companion to this.

Where this is honest about its limits

Where 15Five ends and a cited draft begins

Held in 15FiveWhat PerfCopilot does with it
Objectives and key resultsthe system of recordread-only, per employee, per cycle
The status of each objectiveset by your teammapped to one of four review statuses
The goal periodset by your teammatched against the cycle by overlap
The review prosea cycle and a form to fill indrafted, with each goal claim tagged to the source it came from
Bias screen on the drafted textn/aruns on every draft before you send it
Costvaries by module, see 15five.com/pricingsee our pricing, no seat minimum

The row that earns the connection is the fourth one. Keeping objectives up to date and writing a defensible review from them are different jobs, and the second is the one that eats a manager's week. For the platform-level comparison, including where 15Five is the better tool, read PerfCopilot vs 15Five; if you are weighing leaving instead of layering, 15Five alternatives is the honest version of that question.

Pair 15Five objectives with the work that produced them

An objective says what someone was aiming at. It does not say what they built on the way there, which is why a goals-only review reads thin. The same cycle gets sharper when the objective sits next to the artefacts:

For the wider picture, the performance review software buyer's guide covers where a writing layer sits next to a full HR platform, the engineering performance review template shows what a cited section looks like on the page, and reducing bias in performance reviews explains what the screen on every draft is looking for.

Setting it up

  1. In 15Five, open your avatar menu, then Account and API. Generate a token with the read:goals scope and copy it, because 15Five shows it once.
  2. In PerfCopilot, open Admin and then Integrations, find the 15Five card, paste the token and save. Leave API Base URL (optional) empty unless your tenant sits on another host: https://my.15five.com/api/public appears there as a greyed-out example rather than a filled-in value, and the sync falls back to exactly that address when the field is left blank. Press Test to check the credential against 15Five before anything syncs.
  3. Match each employee to their numeric 15Five user id in the unmapped-employees list. It is the same id 15Five uses in the objective's owner field, which is why a mismatch shows up as zero objectives rather than as an error.
  4. Sync an employee's goals, then generate the review for the active cycle and read which lines carry a goals source tag. The credential walkthrough is in the 15Five setup docs, and the field-by-field mapping, including the status table and the troubleshooting notes, is in the 15Five goals docs.

Prefer to see the output before connecting anything? Run the performance review generator or the standalone bias checker first, and read how connected sources are stored and retained on the security page.

FAQ

What does PerfCopilot read from 15Five? Objectives owned by each matched employee, and the key results nested inside them. From each objective it reads the name, description, status and period dates; from each key result the name, target and status. It is a read-only API token with the goals scope, one endpoint, and nothing is written back into 15Five.

Does it read my weekly check-ins or Best-Self reviews? No. The sync calls the objectives endpoint and nothing else. Weekly check-ins, one-to-ones, engagement surveys and the content of 15Five review cycles are never read. If check-in reflections are the evidence you want in a draft, this integration does not provide them.

Why did my objectives sync as empty? Almost always an unmatched employee. The query filters strictly by the 15Five owner id, so a person with no matched 15Five user returns nothing and the request asks you to match them first. Match the numeric id from your 15Five user list and sync again.

Will the review just score people on goal attainment? No. Goal status is one weighted source among those your competency framework lists, and only the competencies that weight goals draw on it. The draft is told to tag each claim with the source it was drawn from, never to invent data, and to say that data is pending when a weighted source is empty. A bias and fairness screen then runs before a manager sees the draft.

Do I have to move my team off 15Five? No. PerfCopilot is a review-writing layer rather than a platform migration. Your objectives stay in 15Five, PerfCopilot never writes to them, and the finished review leaves as a sealed PDF you file wherever your records already live. There is no seat minimum, so one manager can run it for one team.

Connect 15Five and draft a review → · read-only, no credit card, no seat minimum

Frequently asked questions

What does PerfCopilot read from 15Five?
Objectives owned by each matched employee, and the key results nested inside them. From each objective it reads the name, description, status and period dates; from each key result the name, target and status. It is a read-only API token with the goals scope, one endpoint, and nothing is written back into 15Five.
Does it read my weekly check-ins or Best-Self reviews?
No. The sync calls the objectives endpoint and nothing else. Weekly check-ins, one-to-ones, engagement surveys and the content of 15Five review cycles are never read. If check-in reflections are the evidence you want in a draft, this integration does not provide them.
Why did my objectives sync as empty?
Almost always an unmatched employee. The query filters strictly by the 15Five owner id, so a person with no matched 15Five user returns nothing and the request asks you to match them first. Match the numeric id from your 15Five user list and sync again.
Will the review just score people on goal attainment?
No. Goal status is one weighted source among those your competency framework lists, and only the competencies that weight goals draw on it. The draft is told to tag each claim with the source it was drawn from, never to invent data, and to say that data is pending when a weighted source is empty. A bias and fairness screen then runs before a manager sees the draft.
Do I have to move my team off 15Five?
No. PerfCopilot is a review-writing layer rather than a platform migration. Your objectives stay in 15Five, PerfCopilot never writes to them, and the finished review leaves as a sealed PDF you file wherever your records already live. There is no seat minimum, so one manager can run it for one team.