MCP tool reference
What an AI assistant connected to First can actually do — every tool it can call, and what each one changes.
The First MCP server: connect an AI assistant to First to research a talent market, run the full role lifecycle (create, configure, edit the application process, publish, pause, close, archive), source candidates from the organisation's own candidate database and from the public web, and report on hiring.
Point your assistant at the First MCP server and sign in. Assistants that support it will sign you in with your First account; for tools that need a static credential instead, generate a personal API key in First under Profile, then Personal access tokens.
{
"mcpServers": {
"first": {
"url": "https://api.firststage.co/mcp",
"headers": { "Authorization": "Bearer fst_..." }
}
}
}Every tool below is authorised as you: it can only reach the organisations your account belongs to, roles you are allowed to see are the only ones it can read, and changing a role needs the same admin rights it would in the app. Tools marked CHANGES DATA alter or withdraw something people can see — a good assistant will ask you before running one.
How your assistant is told to use these tools▼
The server hands every assistant these instructions when it connects. They are worth reading: they are what makes an assistant source against agreed criteria rather than guessing, and they explain the sourcing workspace that ties a run of searches together.
First is a recruitment platform. These tools research the talent market, manage roles, find candidates in the organisation's own database and on the public web, add them to roles, and report on hiring. Every tool but one takes an organisationId. Never ask the user for it — call list_organisations and use what comes back. Most people belong to exactly one organisation, so use it without checking; ask which they mean only when there are several. The hiring workflow, when someone is hiring rather than asking a one-off question. Offer it, do not force it — and never walk someone through it who only wanted a number or a database search: 1. RESEARCH the role and market — research_talent_market for demand, pay and who else is hiring. Then suggest a role, with their go-ahead before you create anything. 2. CAPTURE the intake — ask for the hiring manager's brief in whatever form it exists: notes, an interview transcript, a job description. There is no form to fill in, so take it as it comes. 3. CREATE the role — create_role, then generate_suggested_criteria from the brief and update_role_process with them. These criteria are what every candidate added is assessed against. 4. SOURCE a long list — see below — and show it to the user before adding anyone. 5. ADD and PUBLISH — add the people the user chose, then get_role to check readiness and publish_role. Added candidates are assessed against the role's criteria once it is published. Sourcing tools: - search_existing_candidates — people already in the organisation's database: they applied before, so First holds their CV and history. Fast and free. - search_web_for_candidates — people on the public web who have not applied, with a Google X-Ray query. Thin results, and nothing is saved. - save_web_candidates — saves the web results worth keeping to a saved list, looking each person up (paid). Then add_saved_candidates_to_role adds them; get_saved_candidates reads a list and clear_saved_candidates empties it. - add_candidate_to_role — adds existing candidates by candidateId. On organisations on the newer web search, it also takes people on the web by their LinkedIn URL, skipping the save. You do the judging; there is no separate matching step. Read what comes back, keep the people who fit the brief, and let the role's assessment score them once they are added. To source well, first time: - Check existing candidates first, and say so: "I'll check your existing candidates first, then look on the web." Re-engaging someone who applied before beats cold-sourcing a stranger. Go to the web when the database is thin, or straight away when the user asks for new people, the web or LinkedIn. Never make the user pick before you start. - Before searching the web, work out the equivalent job titles (a principal engineer is also a staff, lead or senior staff engineer) and the companies that employ people like this — competitors, companies the user names, companies in the same sector and place. OR the titles together in one query, and run a search per company: a wider net brings back a longer, better list. - Put the place, and any skill that must appear on a profile, into the query text. - Show the user a short reason for each person you suggest, then add the ones they choose. Adding someone already on the role finds their application rather than making another. Searching the database near a place: latitude, longitude and radiusKm need coordinates, and country needs an ISO code, so resolve the name first with geocode_place or geocode_country. If either returns found: false, search without a place rather than guessing coordinates. Before creating a role, gather what it needs: a title, a job description and at least one location are required to publish. Employment type, workplace type and compensation are not required but make the listing usable. Ask the user for anything missing rather than guessing.
The organisations a credential may act on — where the organisationId every other tool needs comes from.
list_organisationsList organisations
The organisations you can act on, with their ids. Every other tool needs an organisationId — call this first to find it rather than asking the user for one. Returns exactly one organisation for most people: use it without asking.
This tool takes no arguments.
Role lifecycle: create, configure, edit the application process, publish, pause, close, archive.
list_rolesList roles
List an organisation's roles, optionally filtered by status. Only returns roles the token owner is allowed to see. Use status 'imported' to find ATS-synced roles awaiting adoption.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| statuses | array of one of: imported, draft, open, paused, closed, archived |
get_roleGet a role
A role's current state: its details, criteria and questions, and readiness — which required details are still missing before it can be published.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
create_roleCreate a role
Create a new draft role. The token owner becomes the hiring manager. Location and category names that don't exist in the organisation are created automatically.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| name* | string | The role title |
| internalName | string | |
| shortDescription | string | |
| description | string | |
| workplaceType | one of: on-site, hybrid, remote, remote-first, flexible | |
| employmentType | one of: full-time, part-time, contractor, internship, volunteer | |
| roleWebsiteUrl | one of 2 shapes | |
| compensation | object | |
| locationNames | array of string | |
| categoryNames | array of string | |
| templateIds | array of string | Role template ids to seed criteria and questions from |
duplicate_roleDuplicate a role
Duplicate an existing role into a new draft, copying its details, settings, criteria and questions. Returns the new role's id.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | The role to copy |
import_roleAdopt an imported role
Adopt a role synced from the ATS: moves it from 'imported' to a draft the team can configure and publish. Use list_roles with status 'imported' to find adoptable roles.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
update_role_detailsUpdate a role's details
Update a role's details. Provide only the fields to change; everything else keeps its current value. Location and category names replace the existing sets. The response lists any fields locked to a connected ATS which kept their synced values.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| name | string | |
| internalName | string | |
| shortDescription | string | |
| description | string | |
| workplaceType | one of: on-site, hybrid, remote, remote-first, flexible | |
| employmentType | one of: full-time, part-time, contractor, internship, volunteer | |
| roleWebsiteUrl | one of 2 shapes | |
| compensation | object | |
| locationNames | array of string | |
| categoryNames | array of string |
publish_rolePublish a role
Publish a role: opens it for applications, putting it live on the job board and apply page and approving any criteria still awaiting review. Also resumes a paused role and reopens a closed one, restarting progress towards any pause goal. Fails with the missing fields when the role's details are incomplete.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
pause_rolePause a role
Pause an open role: candidates can still apply, but new applications wait to be assessed until the role is resumed with publish_role. Fails when the role is not open.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
close_roleCHANGES DATAClose a role
Close an open or paused role: candidates can no longer apply. Reopen it with publish_role. Fails when the role is not open or paused.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
archive_roleCHANGES DATAArchive a role
Archive a role: hides it from active lists and stops new applications. Archived roles can be restored in First. Fails when the role is already archived.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string |
update_role_processCHANGES DATAUpdate a role's application process
Apply changes to a role's application process: its criteria and questions. Each change is one item of the shared process-change contract, applied in order. Criteria changed on a live role may await review and are approved when the role is next published. Use get_role first to see the current criteria and questions.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| changes* | array of one of 19 shapes | The process changes to apply, in order |
remove_role_process_componentCHANGES DATARemove a criterion or question from a role
Remove a criterion or question from a role's application process by process component type and subtype. For stage criteria (type 'assess-stage'), pass the specific criterionId — otherwise every stage criterion on the role would be removed.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| type* | one of: collect-basic-details, check-requirements, check-skills-and-experience, test-knowledge-and-behaviour, ask-video-question, ask-for-document, survey, assess-stage, legacy-criterion, legacy-question | |
| itemType* | one of 8 shapes | |
| questionId | string | |
| criterionId | string | Required for stage criteria (type 'assess-stage'): without it, every stage criterion on the role would be removed |
get_stage_topicsREAD ONLYGet a stage's interview topics
A role's pipeline stages (id, name, kind) and, for the stage given, its interview topics in order: each with its guidance for the interviewer, its questions and follow-ups, and the criteria scored from the answers (id, title, what good looks like, priority, scale). Call it without pipelineStageId to find the stage ids; topics go on interview stages. Read a stage's topics before changing them, so existing topics are changed rather than duplicated.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| pipelineStageId | string |
save_stage_topicsCHANGES DATASave interview topics on a stage
Add or change interview topics on a role's interview stage, each saved with its questions and criteria in one go - typically set up from a client's scorecard or interview template. A topic with a topicId from get_stage_topics is changed; one without is added at the end of its stage (use reorder_stage_topics to move it). Criteria left out of a changed topic are kept, not removed. A section with questions but nothing scored, such as an introduction, is a topic with no criteria. Confirm the topics with the user first.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| topics* | array of object |
reorder_stage_topicsPut a stage's interview topics in order
Put a stage's interview topics in the order the interviewer covers them - for example an introduction first, or the order a scorecard lists them in. Pass every topicId from get_stage_topics in the new order; a topic left out keeps its place after the ones given.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| pipelineStageId* | string | |
| topicIds* | array of string |
remove_stage_topicsCHANGES DATARemove interview topics from a stage
Remove interview topics from a role, by topicId from get_stage_topics. Each topic goes with its questions and the criteria scored under it, and any scores already given for them - the same as removing the topic in First. Always confirm with the user, naming the topics, before calling this.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| topicIds* | array of string |
Search the organisation's applications.
search_applicationsSearch applications
Search the organisation's applications by name or email across every role. Only returns applications for a role the token owner is allowed to see. Use this to find a specific person by name or email address. Omit `query` to list rather than search: `list: "hired"` with no query lists hires, which is how you answer "who have we hired recently" — there is no search term that returns them all. Each row carries `hiredAt`, `shortlistedAt` and `rejectedAt`, so filter to a date window on those rather than on `createdAt`, which is when the application arrived rather than when the outcome happened. **Read `truncated` before quoting any total.** When it is true this is a partial answer — `found` is a lower bound and paging to the end will not reach the rest, so say the count is at least that rather than stating it as the number. Only when `truncated` is false is `found` the whole answer.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| query | string | Name or email to search for. Omit to list the whole of `list` instead — there is no term that returns every hire. |
| field | one of: email, fullName | Restrict matching to one field; omit to match either |
| list | one of: inbox, shortlisted, rejected, hired, all | |
| page | integer |
get_applicationREAD ONLYGet an application
One application's record: which stage it has reached, when it was hired, shortlisted or rejected, where the candidate came from, and its assessment score with the criteria version behind it. Search finds the person; this says what happened to them. Returns not found for a role you are not allowed to see. Their work and education history comes back too, taken from the CV already held against the application — use this rather than the web-sourcing tools for anyone who has applied before: it costs nothing and it is their own CV, not a third-party guess at it. Pass includeProfile: false to leave it out.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| applicationId* | string | The application's id, as returned by search_applications. |
| includeProfile | boolean | Set false to leave out the candidate's CV history. Included by default. |
Find candidates in the organisation's own database and on the public web, and add them to a role as applications.
search_web_for_candidatesREAD ONLYSearch the web for candidates
Search the public web for new candidates — people not in the organisation's database — with a Google X-Ray query (e.g. site:linkedin.com/in with OR-grouped job titles, target employers and must-have skills). It runs on Google, or on Exa for organisations on the newer web search; the query and the results are the same shape either way: a name, a title, a link and a snippet. It saves nothing: pass the ones worth keeping to save_web_candidates. There is no location parameter — put the location into the query text. Cast a wide net: OR together every equivalent job title, and run a search per target employer.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| query* | string | A Google X-Ray query, e.g. site:linkedin.com/in with OR-grouped job titles and must-have skills. There is no location parameter — put the location scope into the query text. |
| num | integer | How many results to return, 1-10. Defaults to 3. |
| start | integer | The 1-based index of the first result, for paging. Defaults to 1; step by `num` to page. |
| dateRestrict | string | Google only; ignored where the organisation's web search runs over public profile pages. |
save_web_candidatesSave web search results
Save up to 10 search_web_for_candidates results to a saved list, ready for add_saved_candidates_to_role. Each is looked up as it is saved: through a paid enrichment where the search ran on Google, from each person's own page where it ran on Exa. Pass the `reference` from an earlier save to keep everything in one list, or omit it to start one and reuse the reference that comes back.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| contacts* | array of object | The profiles worth keeping, built from a prior web search. Send only the ones the caller has decided on: where the search was Google's each is enriched and billed on the way in; where it ran over public profile pages each is built from its page and nothing is billed. |
| reference | string | The saved list to save into. Pass the `reference` from an earlier match or save to keep everything together; omit to start a new one, whose reference comes back in the response. |
add_candidate_to_roleAdd candidates to a role
Add people to a role as applications, wherever they were found. Pass existing candidates as `candidateIds`, from search_existing_candidates, list_candidates or get_candidate: each is added as a copy of their newest application. Pass people on the web as `urls`, their LinkedIn profile URLs — from search_web_for_candidates, or the address of a profile page you are looking at — on organisations on the newer web search; elsewhere, save them with save_web_candidates and add them with add_saved_candidates_to_role. First looks each one up itself, builds a CV from their page and looks up their email and phone (paid lookups) so they can be contacted; nothing else about them is taken from you. Each becomes an application like any other: it is assessed against the role's criteria once the role is published, and synced to the organisation's ATS where that is on. Adding someone already on the role finds their application rather than making another. The response lists who was added, with their application ids, and who could not be.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | The role to add them to. |
| candidateIds | array of string | People already in the organisation's candidate database, by the `candidateId` search_existing_candidates, list_candidates or get_candidate returned. Each is added as a copy of their newest application. |
| urls | array of string | People on the public web, by their LinkedIn profile URL: a `url` the web search returned, or the address of a profile page you are looking at. Only on organisations on the newer web search; elsewhere, save them to a saved list and add them from there. First looks each person up itself; nothing else about them is taken from the caller. |
get_saved_candidatesList a saved list
List every candidate saved under a `reference` — before deciding who to add to a role, or after losing track of what was saved. A role's id lists the role's own list, which First's app sources into. An empty or unknown reference returns an empty list.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| reference* | string | The saved list to show. |
clear_saved_candidatesCHANGES DATAEmpty a saved list
Remove every candidate saved under a `reference`. Starting a fresh reference achieves the same without discarding anything, so prefer that unless the user asks to start this one over.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| reference* | string | The saved list to empty. |
add_saved_candidates_to_roleAdd saved candidates to a role
Add people from a saved list to a role as applications, where they are assessed against its criteria. The contactIds are the ids save_web_candidates or get_saved_candidates returned; pass the list's `reference` too, or omit it for the role's own list. The response lists the ids that were added; ids that no longer resolve to a saved candidate are simply absent.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleId* | string | |
| contactIds* | array of string | The ids of the saved candidates to add to the role as applications — the `id` values a save or a saved list returned. |
| reference | string | The saved list the candidates are on. Pass the `reference` a save returned; omit for the role's own list, which First's app sources into. |
list_candidatesList the candidate pool
List the organisation's candidate pool, most recently applied first: one row per person, however many times they applied. Narrow it by part of a name or email (`text`; a whole address is looked up directly), `discipline`, `rightToWork` or `appliedSince`. The first page says how many match out of the whole pool; pass `nextCursor` back as `cursor` for the next page. For people who fit a role, use search_existing_candidates instead.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| text | string | Part of a name or email address. A whole address is looked up directly. |
| discipline | string | Only people in this discipline: an id from the `disciplines` the first page of list_candidates returns, or 'none' for people without one. |
| rightToWork | string | Only people who said they have the right to work in this country, as an ISO 3166-1 alpha-2 code, e.g. 'GB'. |
| roleId | string | Only people who applied to this role. |
| stage | one of: new, uploading, applied, sourced, invited, in progress, complete, stalled, duplicate, archived, withdrawn, shortlisted, pipeline, hired, rejected | Only people with an application at this stage, e.g. 'shortlisted' or 'hired'. |
| country | string | Only people who applied from this country, as an ISO 3166-1 alpha-2 code (geocode_country turns a name into one). |
| latitude | number | With longitude and radiusKm: only people who applied from near here. |
| longitude | number | |
| radiusKm | number | How far from latitude/longitude, in km (geocode_place gives the point). |
| appliedSince | string | Only people who last applied on or after this date, YYYY-MM-DD. |
| cursor | string | The nextCursor from the previous page, to continue from. |
search_existing_candidatesSearch existing candidates
Find the people in the organisation's own candidate database most like a description, a job title or another candidate, best match first, up to 50. Pass exactly one of `text` (e.g. 'forklift operator', 'React and TypeScript') or `likeCandidateId`. Similarity only: judge the list yourself, then add the people worth it with add_candidate_to_role, where the role's assessment scores them.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| text | string | What to look for: skills, a job title or a short description of the person, e.g. 'forklift operator' or 'React and TypeScript'. |
| likeCandidateId | string | Find people like this candidate instead of matching text. |
| discipline | string | Only people in this discipline: an id from the `disciplines` the first page of list_candidates returns, or 'none' for people without one. |
| rightToWork | string | Only people who said they have the right to work in this country, as an ISO 3166-1 alpha-2 code, e.g. 'GB'. |
| roleId | string | Only people who applied to this role. |
| stage | one of: new, uploading, applied, sourced, invited, in progress, complete, stalled, duplicate, archived, withdrawn, shortlisted, pipeline, hired, rejected | Only people with an application at this stage, e.g. 'shortlisted' or 'hired'. |
| country | string | Only people who applied from this country, as an ISO 3166-1 alpha-2 code (geocode_country turns a name into one). |
| latitude | number | With longitude and radiusKm: only people who applied from near here. |
| longitude | number | |
| radiusKm | number | How far from latitude/longitude, in km (geocode_place gives the point). |
get_candidateGet a candidate and their applications
One person in the candidate pool and what they have applied to, newest first, by the candidateId list_candidates or search_existing_candidates returned. Applications on roles you can't see are left out. Use get_application for an application's full detail.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| candidateId* | string |
geocode_placeResolve a place to coordinates
Turn a city or place name into the coordinates a 'radius' search needs. Call this before sourcing near somewhere, then pass the coordinates as `location`. Returns found: false when the name is not an actual city (a whole country, or unrecognisable) — use geocode_country for a country, or fall back to searchType 'everywhere'.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| name* | string | The place to resolve, e.g. 'London' or 'Leeds, UK'. |
geocode_countryResolve a country to its ISO code
Turn a country a recruiter named — 'United Kingdom', 'UK' or 'GB' — into the ISO 3166-1 alpha-2 code a 'country' search needs. Call this before sourcing country-wide, then pass the code as `country`. Returns found: false when the value is not a recognisable country.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| name* | string | The country to resolve, e.g. 'United Kingdom'. |
Generate a role's assessment criteria from its title and job description.
generate_suggested_criteriaGenerate suggested role criteria
Generate a role's assessment criteria from its title and job description. Returns process changes ready to apply to a role (update_role_process) — the criteria every candidate added to it is assessed against. Nothing is created or changed: show the criteria to the user, adjust if they want, then apply them. `requirementsPreview` summarises what they ask for, which also tells you who to look for when sourcing. ALWAYS pass `roleId` when the role already exists — when you are working on a role rather than drafting one. That is what pulls in its intake call transcripts and note-taker summaries, which say what the hiring manager actually asked for; a job description is often boilerplate. Omitting it silently generates from the description alone. Omit it only while the role is still a draft.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| title* | string | The role title. |
| jobDescription | string | The role's job description. The richer this is, the better the criteria. |
| keywords | array of string | Skills the hiring manager called out, when there is no job description yet. |
| roleId | string | An existing role to draw intake material from. Its saved intake call transcripts and note-taker summaries are read in alongside the job description. Omit when the role does not exist yet. |
Research the talent market for a role — pool depth, pay and who else is hiring. The only tools here that reach the web.
research_talent_marketResearch a talent market
Research the talent market for a role — how deep the pool is, what it pays, and who else is hiring for it. Use it before committing to a hire, to sanity-check a salary, or to tell the user whether a location is realistic. Searches the web, not the organisation's candidate database (search_existing_candidates does that). Nothing is created or changed. `location` is a place as the recruiter would say it — 'London', 'the UK' — not coordinates or an ISO code. A market it finds nothing for returns found: false; say so rather than retrying.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | |
| roleTitle* | string | The role to research, e.g. 'Software Engineer'. |
| location* | string | Where to research it, as the recruiter would say it — 'London', 'the UK', 'Berlin'. Not a coordinate or ISO code. |
| seniorityLevel | string | The seniority to narrow to, e.g. 'senior', 'lead'. |
| additionalContext | string | Anything else that shapes the market, e.g. an industry or a required technology. |
Monthly usage reporting.
get_monthly_reportingGet monthly recruitment reporting
Monthly reporting for an organisation: one row per role with application volumes (in period, total, last 7/30 days, rolling daily averages), hires and time to hire (average/median days), completion funnel percentages (started, complete, shortlisted), stalled and aged application counts, role status and whether the role uses AI assessment. Defaults to the latest available month. Use this to compare roles; use get_reporting_summary for org-wide trends and get_stage_reporting for pipeline bottlenecks.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | The organisation to report on. |
| month | string | Report month in YYYY-MM format. Omit for the latest available month. |
get_stage_reportingGet pipeline stage reporting
Pipeline funnel reporting for an organisation: one row per role per pipeline stage, in pipeline order, with how many applications reached each stage and the average/median days spent in it. Use this to find where candidates drop off or wait the longest (pass-through rates, bottlenecks). Defaults to the latest available month. Months before stage metrics existed return no rows.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | The organisation to report on. |
| month | string | Report month in YYYY-MM format. Omit for the latest available month. |
get_reporting_summaryGet organisation reporting summary
Organisation-level trend reporting: one row per month with totals across every role — application volumes, hires and time to hire (average/median days), completion funnel percentages, aged applications and the share of roles using AI assessment. Use this first for topline questions and month-on-month trends. from/to are inclusive YYYY-MM bounds (at most 24 months); omit both for the trailing 12 months. Months without a report are omitted.
| Field | Type | Description |
|---|---|---|
| organisationId* | string | The organisation to report on. |
| from | string | First month in YYYY-MM format, inclusive. |
| to | string | Last month in YYYY-MM format, inclusive. |
The same operations are available over HTTP — see the REST API reference.