Create-or-Update Ergonomics
For providers that ACCEPT WRITES only: can a caller create-or-update in one call, keyed on an identifier the caller already holds, and does the response say which branch ran? Without it every write needs a hand-rolled search-and-branch in front of it, and the first time that check is skipped the customer's records grow a duplicate. A provider that ships it has made a checkable commitment about who owns identity resolution — them, not the integrator. Not applied to read-only APIs, and not applied where no contract could be parsed: a reference API is not deficient for being unable to upsert.
How it is scored
4 checks worth 36 points, grouped by the artifact each one reads. A facet's sub-score is its awarded points normalized against the points that were actually applicable to that provider — a check needing an artifact the provider does not publish at all is N/A, and leaves both sides of the fraction.
upsert| Check | Rule | Points |
|---|---|---|
| The response says which branch ranThe scarce one, and the one that matters: 1.4% of providers that accept writes. Upsert you cannot reconcile afterwards is upsert you have to trust. Without a discriminator a caller cannot tell an insert from an update without re-reading, which is the search-and-branch the upsert was supposed to remove. Priced highest because it is both the rarest signal and the one that changes what an integrator can safely build. | a create-or-update response carries a boolean discriminator (new, created, is_new, was_created) | 14 |
| The caller declares the key to match on9.8%. This is where identity resolution actually changes hands: the provider agrees to match on an identifier the caller already owns rather than making the caller discover the provider's own id first. Includes Salesforce's PATCH /sobjects/{OBJECT}/{FIELD}/{value} path shape, which expresses the same commitment in the URL instead of the body. | a write operation accepts a caller-named natural key (idProperty, external_id, match_on, on_conflict, id_type) or an alternate-key path shape | 10 |
| A named create-or-update operation12.3%. The capability is discoverable from the contract without reading prose. Priced below the alternate key deliberately: naming an operation `upsert` is a claim, whereas accepting a caller's key is a commitment. | an operation is named as an upsert or a create-or-update in its path, operationId or summary | 8 |
| Duplicate handling is stated at all9.2%, and worth little on purpose. This is the capability existing but undiscoverable — stated only in prose ("creates it if it does not exist", usually on PUT /{id}), or bolted onto create as a boolean (Twenty CRM's `upsert: true`). It is real and a caller can use it, but it cannot be found by reading the contract's shape, so it earns a fraction of a named operation. | the create endpoint carries a conflict/duplicate-handling flag, or the description states create-if-absent behaviour | 4 |
Top providers
The other 8 facets
github.com/api-evangelist/<provider>, and each check above names the exact artifact it
reads. Publish the artifact, open a pull request, and the next scoring run picks it up — no gatekeeping
and no fee. The full rubric is at apis.io/rating/, and the
Influence plan is the fast lane if you would rather
work your own listing through the API — remediation, projections and re-check requests.
Scored on rubric v0.20.0 across 26,755 providers · lists rebuilt 2026-09-07 · capped at the top 500 per page.