Use cases
What teams build on the Agent API, with the calls behind each, and how to connect Copilot Studio
What recruitment teams build on the Agent API, each with the calls it takes. Every example uses $WINTRO_TOKEN and https://www.wintro.app.
A sourcing agent that searches warm before cold
A recruiter asks their agent for candidates for a vacancy. The agent tries the people the company already knows first (its ATS, then Wintro’s network of colleagues) and goes to LinkedIn search only for what is left.
Recruiter: "Find me D365 F&O consultants for VAC-2291."
1. vacancies/list {"atsId": "VAC-2291"} → vacancyId 4182 (live: true)
2. candidates/ranked {"vacancyId": 4182, "limit": 10} → likeliest hires, each with introducers
3. answer name, current job, "Pieter De Smet knows her", wintroUrl
4. only if too few search LinkedIn, then candidates/lookup {"linkedins": [...]} for everyone found there, in one call
The vacancy id from your ATS (Carerix, say) is enough: atsId finds it in Wintro. If live is false, Wintro has no candidates for it yet: stay with your ATS and LinkedIn. Ranked candidates need no lookup: blocked and closed ones are left out, and each row says what already happened.
Check before anyone reaches out
Your ATS does not see LinkedIn messages sent or a colleague’s referral in progress. Before an agent or recruiter contacts people found outside Wintro (your ATS, a LinkedIn search), look them up, up to 25 in one call:
curl -s https://www.wintro.app/api/wintro/app/candidates/lookup \
-H "Authorization: Bearer $WINTRO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"linkedins": ["https://www.linkedin.com/in/lotte-janssens", "jan-peeters", "els-maes"]}'
{
"people": [
{
"linkedin": "https://www.linkedin.com/in/lotte-janssens",
"found": true,
"profile": { "profileId": 55120, "name": "Lotte Janssens" },
"introducers": [{ "name": "Pieter De Smet", "profileUrl": "https://www.linkedin.com/in/pieter-de-smet" }],
"matches": [{ "matchId": 918273, "vacancyId": 4182, "vacancyTitle": "Dynamics 365 F&O Consultant", "vacancyOpen": true, "score": 84, "status": "referred by Pieter De Smet: interview", "wintroUrl": "https://www.wintro.app/dashboard/candidates/4182/live?search=55120" }]
},
{ "linkedin": "jan-peeters", "found": true, "blocked": true, "profile": { "profileId": 61002, "name": "Jan Peeters" } },
{ "linkedin": "els-maes", "found": false }
]
}
blocked: true: your recruiters blocked or snoozed them. Stop.- A match whose
statusstarts withreferred,recommendedor a stage word without a date (interview,contacted,hired): a colleague’s referral is running. Don’t approach them separately. contacted 5 Oct, with a date: a recruiter already reached out.rejected 6 Octornot a fit, says An Claes 2 Oct: your team already decided against them for that vacancy.introducers: ask one of them for a warm introduction instead of a cold message.found: false: nobody here knows them. A cold approach is yours to decide.
Each person counts as one call against your limits.
Let your ambassadors do the introducing
Instead of messaging the candidate, the agent tells the recruiter which colleague to ask for an introduction, and whether they were asked already:
curl -s https://www.wintro.app/api/wintro/app/candidates/introducers \
-H "Authorization: Bearer $WINTRO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"matchId": 918273}'
nudgedAt: null: nobody asked this colleague yet. The recruiter opens the candidate’s wintroUrl and asks from Wintro, so the referral and its reward are tracked.
Who does this team know?
Start from people instead of a vacancy: the candidates a team, a manager or a new hire knows for one vacancy.
curl -s https://www.wintro.app/api/wintro/app/candidates/ranked \
-H "Authorization: Bearer $WINTRO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vacancyId": 4182,
"colleagues": [
"https://www.linkedin.com/in/pieter-de-smet",
"https://www.linkedin.com/in/an-claes"
]
}'
Colleagues who don’t share their network come back in unknownColleagues.
A morning digest
A script for each open vacancy: the strong candidates nobody has acted on (no status), posted to your team’s channel.
import os, requests
API = "https://www.wintro.app/api/wintro/app/"
H = {"Authorization": f"Bearer {os.environ['WINTRO_TOKEN']}"}
call = lambda action, body: requests.post(API + action, json=body, headers=H).json()
for v in call("vacancies/list", {"live": True})["vacancies"]:
fresh = [c for c in call("candidates/ranked", {"vacancyId": v["vacancyId"], "minScore": 80})["candidates"]
if "status" not in c]
for c in fresh[:3]:
who = ", ".join(i["name"] for i in c.get("introducers", [])) or "nobody yet"
print(f'{v["title"]}: {c["name"]} ({c.get("currentTitle", "?")}), known by {who}: {c["wintroUrl"]}')
Copilot Studio
Download the connector file
A recruiter admin, in Wintro, Settings > API: download
wintro-connector.swagger.jsonunder Agent API (it shows only when your plan includes it). Create a token there too, with Agent API ticked.Make a custom connector
In Power Apps, Custom connectors > New custom connector > Import an OpenAPI file, and pick that file. Security is already set: an API key in the
Authorizationheader.Connect
Create a connection and paste
Bearerfollowed by your token, with the space:Bearer wintro_...Add the actions to your agent
In Copilot Studio, add the connector’s actions under Tools. Each action carries a description written for the agent, so it knows when to use it.
Then give your agent its instructions. A start to paste and adapt:
You help our recruiters find candidates through people we already know.
- Start a run with agent/status. If an action is paused, say so and use the others.
On a 429 or 503, wait the Retry-After seconds before trying again.
- For a vacancy from our ATS, find it with vacancies/list {"atsId": "..."}.
If it is not live, Wintro has no candidates for it: say so and search elsewhere.
- Get candidates with candidates/ranked, best first. Always name who can introduce
each one, and link the wintroUrl.
- Candidates from candidates/ranked are already checked. Anyone found elsewhere
(our ATS, a LinkedIn search): run candidates/lookup on their LinkedIn URLs first,
all of them in one call with linkedins.
Never suggest contacting someone blocked, with a referral running, or already
contacted (a status with "contacted" and a date).
- Prefer a warm introduction by a colleague over a cold message.
