Skip to content

Editing your company profile

Prok keeps your profile current on its own, from email replies and portal feedback (see Company profile). You can also change it yourself, in the portal or through the API. Both paths write the same fields, land in the same change history, and are undone the same way.

The portal’s Company Profile page carries an Edit control on each card:

Card Fields
What you sell Categories, manufacturer partners, target buyers
Where Geography
Qualifications Certifications
Constraints Exclusions, business role, Canadian supplier, employees, minimum and maximum contract value
Overview Overview

The identity card at the top has no Edit control. Legal name, business number, and CAGE code are managed by Prokure: to change one, contact your Prokure representative.

PATCH /api/v1/profile requires the profile:write scope and takes a batch of between 1 and 50 operations:

Terminal window
curl -X PATCH "https://app.prokure.ca/api/v1/profile" \
-H "Authorization: Bearer $PROKURE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"updates": [
{ "field": "certifications", "op": "add", "value": "ISO 9001" },
{ "field": "geography", "op": "remove", "value": "Yukon" },
{ "field": "employee_count", "op": "set", "value": 45 }
]
}'

The operations are applied in order, and the response accounts for every one of them. profile is the profile as it stands afterwards, in the same shape GET /api/v1/profile returns (abbreviated below), and applied holds the same change objects GET /api/v1/profile/changes returns:

{
"profile": {
"certifications": ["CGP", "ISO 9001"],
"employee_count": 45
},
"applied": [
{
"id": "b4b6b8b0-0000-0000-0000-000000000000",
"field": "certifications",
"value_before": ["CGP"],
"value_after": ["CGP", "ISO 9001"],
"cascade_summary": { "products_deactivated": 0, "products_reactivated": 0 },
"source": "portal_edit",
"created_at": "2026-09-05T14:03:11.000Z",
"reverted": false,
"revertible": true
}
],
"skipped": [
{
"field": "geography",
"op": "remove",
"value": "Yukon",
"reason": "not_present",
"message": "Skipped removing \"Yukon\" from geography — not on your profile. Current: Ontario; Quebec."
}
]
}
Field Operations Value
categories, geography, certifications, exclusions, manufacturer_partners, target_buyers add, remove A string of 1 to 200 characters.
overview set A string of 1 to 4000 characters. It cannot be cleared through this endpoint.
business_role set manufacturer, distributor, integrator, services, or null.
is_canadian_supplier set true, false, or null.
min_contract_value, max_contract_value set A non-negative integer, or null. The minimum may not exceed the maximum.
employee_count set A non-negative integer, or null.

Adding to a list de-duplicates case-insensitively, and removing from one matches case-insensitively against what the list already holds, so an operation phrased as iso 9001 finds an existing ISO 9001. Where the same field appears more than once in one request, the last operation for it is the one that stands. When a request sets both contract-value bounds, the pair it ends on is validated together rather than one bound at a time, so raising both at once is not rejected on the strength of the other bound’s old value.

Legal name, business number, and CAGE code are identity fields, and no operation on them is accepted. A field name the profile does not have, a key the operation shape does not define, an operation a field does not accept, or a batch outside the 1 to 50 range is rejected with 400 validation_failed. In that case nothing is written at all: the request is validated before any of it is applied.

An operation that is skipped is not an error. The request still succeeds, and every other operation in it still applies. Each entry in skipped repeats the field, op, and value you sent, plus a reason and a message. The message is written for a person to read and its wording may change, so branch on reason, never on message:

reason What happened
already_present An add whose value is already on that list.
not_present A remove whose value is not on that list, so there is nothing to take off it.
already_set A set whose value is what the field already holds.
min_exceeds_max The minimum contract value the request would land on is above the maximum.
invalid_value The value is not one this field accepts.
error The change failed on our side. Nothing was written for it, and the failure is recorded for us.

already_set is a skip rather than a silent success on purpose. Writing a change that changes nothing would make it that field’s newest history entry, and that would block reverting the change before it, which is the one that actually did something.

Every applied operation becomes an ordinary entry in the change history, with source set to portal_edit and the label You — portal edit on the portal’s history card. It behaves exactly like a change Prok made itself: it appears in GET /api/v1/profile/changes, and POST /api/v1/profile/changes/{id}/revert undoes it for as long as it is still the latest change to that field. See Change history and Reverting a change for the full rules.

Because applied carries the same objects the history endpoint returns, the id in a PATCH response is the id to pass to revert, with no lookup in between.

Removing a manufacturer partner deactivates that partner’s catalog products in the same change, so they stop counting toward match scores immediately. The entry’s cascade_summary reports how many, and reverting the removal brings the partner and those products back. The portal’s removal dialog tells you the count before you confirm, and the Product catalog page is where you can see which products those are. Adding a partner is not symmetrical: it records the name only, and a newly added partner influences scoring only once their catalog has been onboarded separately.

An edit changes what Prok scores against, so the opportunities it affects are re-scored in the background. The results reach you in your next digest rather than in an email of their own.

  • 50 operations per request. Batch related changes into one call rather than sending them one at a time.
  • 10 requests per minute, counted per client IP like every other write route. See Rate limits and errors.