Published API
Published API
All these api calls are HTTPS only and rooted at your tenant. For example: https://your-tenant.pathfinderedge.com/api/v1/profiles.
This API reads and writes your profile library, and reports your machines' connection and sync status (read-only). It does not send profiles to a machine — machines pull their own updates on a schedule, filtered by catalog. See Machine sync before integrating, especially if your goal is to get a profile onto a machine.
Security
The Edge api uses api keys to provide authentication. Users generate their own keys using their tenant on the Pathfinder Edge website. Using an admin account, login to a tenant and navigate to Admin -> Api Keys. From there you can view and create keys. Eventually, you will be able to revoke/delete them here as well.
Api keys are a roughly 40 character string.
Authorization header raw, with no scheme prefixAuthorization: OQNRuUVWSEcyMkJZSEhYSlg3SEEHoTdMMzZ9SlA4
The server compares the entire header value against your key. Anything you add in front of it — or any transformation of the key itself — makes the comparison fail and returns 401. These all fail:
| Header sent | Result |
|---|---|
Authorization: <key> | ✅ correct |
Authorization: Bearer <key> | ❌ 401 — the scheme prefix is part of the compared value |
Authorization: ApiKey <key> | ❌ 401 — this is the Eclipse Pro format, not Edge's |
X-API-Key: <key> | ❌ 401 — this header is not read at all |
Authorization: <base64-decoded key> | ❌ 401 — send the key exactly as issued; do not decode it |
Keys are usable the moment they are created — there is nothing to activate, and there are no scopes or per-endpoint permissions. A key grants full access to its tenant's library.
Here is an example http post to create a new profile using the web api.
POST /api/v1/profiles HTTP/1.1 Host: ams-test.pathfinderedge.com Authorization: OQNRuUVWSEcyMkJZSEhYSlg3SEEHoTdMMzZ9SlA4 Content-Type: application/json Cache-Control: no-cache
{
"profileName": "A Sample Profile",
"description": "Quite nifty",
"owningCatalogId": 1,
"category": "Quirky Parts",
"subCategory": "Awkward",
"features": [
{"type":"Straight", "length":0.5},
{"type":"OpenHem", "hemHeight": 0.25, "hemDirection":"Negative"},
{"type":"Straight", "length":10},
{"type":"Angle", "angle": 90.0},
{"type":"Straight", "length":10},
{"type":"TearDropHem", "hemDirection":"Positive"},
{"type":"Straight", "length":0.5}
]
}
The Authorization header, OQNRuUVWSEcyMkJZSEhYSlg3SEEHoTdMMzZ9SlA4, is the api key.
Diagnosing a 401
A 401 response body tells you which of the two failure modes you hit:
{
"error": "You are unauthorized to make this request.",
"reason": "SchemePrefixed",
"expectedFormat": "The Edge API expects the API key as the raw Authorization header value, with no scheme prefix (Authorization: <key>) — not 'Bearer <key>', not 'ApiKey <key>', and not base64-decoded. Generate keys under Admin > Api Keys.",
"keyFingerprint": "9f2a1c4d7b03"
}
reason | Meaning |
|---|---|
MissingHeader | No Authorization header, or it was blank. |
SchemePrefixed | The value carried a scheme prefix (Bearer, ApiKey, Basic, …). Send the raw key. |
UnknownKey | Correctly formatted, but no key on this tenant matches. Either the key is wrong or it was deleted — keys are deleted outright, not marked revoked, so the two are indistinguishable by design. |
keyFingerprint is a short non-reversible hash of what you sent. It is safe to quote in a support
request and lets us match your attempts to our server-side logs; identical values mean you sent the
same key twice. Failed attempts are logged server-side with this fingerprint, so support can confirm
what reached us without you ever sharing the key.
List Profiles
Returns list of profiles in json format.
-
URL
/api/v1/profiles -
Method:
GET -
URL Params
Optional:
catalog=[integer]— return only profiles in this catalog.skip=[integer]andtake=[integer]— paging. Both are required together; sending only one, orskip < 0/take < 1, returns 400 rather than falling back to a default.
Archived (deleted) profiles are never returned.
-
Data Params
None
-
Success Response:
- Code: 200
Content:
- Code: 200
[{
"profileId": 10001,
"profileName": "test1",
"description": "A sample profile",
"owningCatalogId": 1,
"category": "",
"subCategory": "",
"blankWidth": 4.75,
"bendCount": 3,
"hemCount": 1
}, ... ]
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 400 BAD REQUEST
Content: empty — an invalidskip/takepair
-
Get Profile
Returns single profile in json format.
-
URL
/api/v1/profiles/:id -
Method:
GET -
URL Params
Required:
id=[someidvalue]Profile Id
-
Data Params
None
-
Success Response:
- Code: 200
Content:
- Code: 200
{
"profileId": 10001,
"profileName": "test1",
"owningCatalogId": 1,
"category": "",
"subCategory": "",
"blankWidth": 4.75,
"bendCount": 3,
"hemCount": 1
}
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 404 NOT FOUND
Content: empty — the profile does not exist, is archived, or belongs to another tenant. These are deliberately not distinguished.
-
Post Profile
Create a new profile.
-
URL
/api/v1/profiles -
Method:
POST -
Data Params
A profile object in json format, in the body. See The profile object for the full field-by-field format, including which fields apply to which feature type.
Two fields deserve attention:
-
owningCatalogId— optional, but if you send it, it must be the id of a catalog belonging to your tenant; anything else is a 400. Get valid ids from List Catalogs. If you omit it, the profile lands in your tenant's default catalog.Which catalog you choose determines which machines can see the profileA machine only receives profiles from the catalogs it is subscribed to under Admin > Machines > (your machine). Posting to a catalog no machine subscribes to succeeds and is a perfectly valid library entry — it just never reaches a machine. See Machine sync.
-
blankWidth— not accepted on input; the server computes it as the sum of your feature lengths and returns it in the response. Sending it has no effect.
-
-
Success Response:
- Code: 200
Content:
- Code: 200
{
"profileName": "test1",
"owningCatalogId": 1,
"category": "",
"subCategory": "",
"blankWidth": 4.75,
"bendCount": 3,
"hemCount": 1
}
Upon successfully posting a new profile, the profile header data is echoed back. profileId (notably absent in the sample
above) will be assigned by the server, and can be used to fetch the header details for this profile later.
Check the echoed owningCatalogId and blankWidth — they confirm which catalog the profile actually
landed in and what the server computed, which is what a machine will act on.
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 400 BAD REQUEST
Content:[ "Hems must have a hemDirection of 'Positive' or 'Negative'.", "Radius bends require a non-negative radius." ]
-
Bad request errors mean the profile data failed validation. It will be a list of messages that hopefully highlight the problem.
[ "OwningCatalogId must refer to a valid catalog." ] means the catalog id you sent is not one of your
tenant's catalogs.
Get Profile Thumbnail
Returns a rendered image of the profile. Useful for showing an operator or a picker what a profile looks like without reimplementing the geometry.
-
URL
/api/v1/profiles/:id/thumbnailor/api/v1/profiles/:id/thumbnail.png— PNG
/api/v1/profiles/:id/thumbnail.svg— SVG -
Method:
GET -
URL Params
Required:
id=[someidvalue]Profile Id
-
Success Response:
- Code: 200
Content: the image,image/pngorimage/svg+xml. Rendered on request, white-on-black.
- Code: 200
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 404 NOT FOUND
Content: empty
-
Delete Profile
Remove the profile from the catalog.
Deleting archives the profile rather than erasing it: it stops appearing in list/get results, and the deletion propagates to every machine subscribed to its catalog on that machine's next sync.
-
URL
/api/v1/profiles/:id -
Method:
DELETE -
URL Params
Required:
id=[someidvalue]Profile Id
-
Data Params
None
-
Success Response:
- Code: 200
Content:
None
- Code: 200
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 404 NOT FOUND
Content: empty
-
List Catalogs
Returns list of catalogs in json format. Start here: these are the only valid values for
owningCatalogId when posting a profile.
-
URL
/api/v1/catalogs
-
Method:
GET -
URL Params
None
-
Data Params
None
-
Success Response:
- Code: 200
Content:
- Code: 200
[{
"catalogId": 1,
"catalogName": "Standards"
}, ... ]
-
Error Response:
- Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401
- Code: 401 UNAUTHORIZED
This endpoint is the quickest way to confirm a key works — it needs no body and no parameters.
GET /api/v1/catalogs HTTP/1.1 Host: your-tenant.pathfinderedge.com Authorization: OQNRuUVWSEcyMkJZSEhYSlg3SEEHoTdMMzZ9SlA4
List Machines
Returns your registered Pathfinder machines with their connection and sync status, for monitoring. Machines are sorted by name. Disabled machines (retired, replaced, or blocked from syncing) are left out unless you ask for them.
This endpoint is read-only. It reports what each machine has received; it cannot trigger or expedite a sync (see Machine sync).
-
URL
/api/v1/machines -
Method:
GET -
URL Params
Optional:
includeDisabled=[true|false]— include disabled machines. Defaultfalse.status=[status]— return only machines with this status (see below), e.g.status=behind. Case-insensitive.status=disabledimpliesincludeDisabled=true.
-
Data Params
None
-
Success Response:
- Code: 200
Content:
- Code: 200
[{
"id": "d7cfbef4-fac7-421d-acca-5ba9d7521364",
"serialNumber": "P0720000",
"machineName": "Line 1",
"location": "Plant 2",
"catalogIds": [10000, 10002],
"applicationVersion": "4.10.4.2003",
"status": "syncing",
"lastContactAt": "2026-09-24T14:02:11Z",
"minutesSinceLastContact": 3.2,
"syncedThrough": "2026-09-23T21:40:05Z",
"progress": { "received": 1500, "total": 12123 },
"pendingChangeCount": 10623,
"errorCode": null
}, ... ]
| Field | Meaning |
|---|---|
id | The machine's id. Use it with Get Machine. |
catalogIds | The catalogs the machine subscribes to — the same ids List Catalogs returns. Only profiles in these catalogs reach this machine. |
status | Sync status, one of the values below. |
lastContactAt | When the machine last contacted Edge (UTC), or null if it never has. |
minutesSinceLastContact | The same, as minutes ago. Alert when this exceeds a threshold that suits your machines. |
syncedThrough | The machine has confirmed receiving every profile change in its catalogs up to this time (UTC). |
progress | While syncing: profiles received so far, out of the total for this sync. Otherwise null. |
pendingChangeCount | Profile changes in the machine's catalogs that it has not received yet. null when the machine's sync position is unknown (see status). |
errorCode | The error from the machine's last request, if any. |
status | Meaning |
|---|---|
upToDate | The machine has every change in its catalogs. |
behind | There are changes the machine has not received yet. This is normal for a short while after profiles are edited, until the machine's next check, so alert on it only if it persists. |
syncing | The machine is downloading changes, or has downloaded them and not yet confirmed (it confirms on its next check, about a minute later). A machine that stays syncing for a long time is not completing its downloads and needs attention; syncedThrough shows how far back it is. |
awaitingSync | The machine has connected but has not checked for changes since. |
error | The machine's last request failed; see errorCode. |
neverConnected | The machine is registered but has never connected. |
disabled | The machine is retired or blocked from syncing. |
A machine that is upToDate but has not been in contact for a long time is up to date as of
lastContactAt — it has not seen anything changed since. Monitor minutesSinceLastContact
alongside status.
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 400 BAD REQUEST
Content:[ "status must be one of: disabled, neverConnected, error, awaitingSync, syncing, behind, upToDate." ]
-
Get Machine
Returns a single machine and its status, in the same format as List Machines. Disabled machines are returned too.
-
URL
/api/v1/machines/:id -
Method:
GET -
URL Params
Required:
id=[guid]Machine id, from List Machines
-
Data Params
None
-
Success Response:
- Code: 200
Content: a single machine object, as above.
- Code: 200
-
Error Response:
-
Code: 401 UNAUTHORIZED
Content: see Diagnosing a 401 -
Code: 404 NOT FOUND
Content: empty — the id is not a valid guid, does not exist, or belongs to another tenant. These are deliberately not distinguished.
-