Send x-api-key. Read-only keys cannot write or delete.
A simple entity HTTP API.
Create, read, update, delete, and list JSON or EDN entities.
Send JSON or EDN. Use .json or .edn for the response.
Body max: 1 MB. Batch max: 20 entities. Query pagination sizes: 20, 50, or 100.
Start in three steps
Set the URL and key. Create, patch, then read an entity.
- Set API_BASE_URL and SHIP_DEPLOY_API_KEY.
- Create an entity.
- Patch its data.
- Read it by id.
export API_BASE_URL=https://shipdeploy.work/api/v1
export SHIP_DEPLOY_API_KEY=replace-with-your-api-keycurl -X POST "$API_BASE_URL/entities.json" \
-H 'content-type: application/json' \
-H "x-api-key: $SHIP_DEPLOY_API_KEY" \
-d '{"id":"person-ada","type":"person","labels":{"region":"za"},"data":{"name":"Ada","active":false,"profile":{"city":"London"}}}'curl -X POST "$API_BASE_URL/entities/patch.json" \
-H 'content-type: application/json' \
-H "x-api-key: $SHIP_DEPLOY_API_KEY" \
-d '{"id":"person-ada","patches":[["assoc","active",true],["assoc-in",["profile","email"],"ada@example.com"],["deep-merge",{"profile":{"city":"Cape Town"}}]]}'curl -X POST "$API_BASE_URL/queries/find-entity-by-id.json" \
-H 'content-type: application/json' \
-H "x-api-key: $SHIP_DEPLOY_API_KEY" \
-d '{"id":"person-ada"}'Review every change
Every write adds a version. Deleted entities keep their history.
Evict removes the entity and all history.
List change metadata. No data or diffs.
Get one version snapshot.
Keys select the tenant
Each tenant has separate data and keys. Clients do not send tenant ids.
Write keys change data. Read-only keys can only read and list.
Every key is scoped to one tenant.
Create, update, and delete entities.
Read and list without changing data.
The API key handles isolation for you.
What the API does
Create, read, update, delete, and list entities. Advanced operations remain available when you need them.
Check service health
Return status and deployed version.
Create an entity
Store one entity. The server can create the id.
Find one entity
Return one entity by id.
Find entities by type
Return a page of one entity type.
Find entities by attributes
Match fields in entity data.
Find entities by labels
Match every supplied label.
Upsert an entity
Create or replace an entity by id.
Update an entity
Update an existing entity. Missing ids return 404.
Patch entity data
Apply ordered patches to entity data.
Replace entity labels
Replace labels. An empty map clears them.
Create multiple entities
Store up to 20 entities together or independently.
Delete an entity
Soft delete hides it. Hard delete removes it. Both keep history.
Evict an entity
Permanently remove the entity and history.
List entity history
List version and change metadata.
List entity changes
Alias for entity history.
Get one history version
Return one version snapshot.
Get recent entities by type
Return the latest 20 entities of one type.
Inspect one object structure
Infer one object's fields and types. No key required.
Inspect one stored entity
Infer one stored entity's structure.
Inspect stored data by type
Show common and uncommon fields for one type.
Configure an entity type
Set display names and relationship rules.
Define a relationship
Define a relationship between entity types.
Link related entities
Link two existing entities.
Unlink related entities
Remove a link and record the change.
List entity relationships
List links for one entity.
Get relationship graph
Return an entity and its neighbours.
Infer relationships
Create links from configured id fields.
Check health
Confirm the service and deployed version.
curl https://shipdeploy.work/health.jsonCreate an entity
Store one entity. Omit id to create one.
curl -X POST https://shipdeploy.work/api/v1/entities.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","type":"person","labels":{"region":"za","workflow/status":"active"},"data":{"name":"Ada","active":true,"department":"research"}}'Find one entity
Read one entity by id.
curl -X POST https://shipdeploy.work/api/v1/queries/find-entity-by-id.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada"}'Find entities by type
Page sizes: 20, 50, or 100. Sort by id, type, created-at, or updated-at.
curl -X POST https://shipdeploy.work/api/v1/queries/find-entities-by-type.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"type":"person","page":1,"page-size":20,"sort-by":"updated-at","sort-direction":"desc"}'Find entities by attributes
Match fields in entity data.
curl -X POST https://shipdeploy.work/api/v1/queries/find-entities-by-attributes.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"attributes":{"department":"research","active":true},"page-size":20}'Find entities by labels
Labels sit outside data. Every supplied label must match.
curl -X POST https://shipdeploy.work/api/v1/queries/find-entities-by-labels.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"labels":{"region":"za","workflow/status":"active"},"page-size":20}'Upsert by id
Create or replace an entity by id.
curl -X POST https://shipdeploy.work/api/v1/entities/upsert.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","type":"person","data":{"name":"Ada Lovelace","active":true}}'Update by id
Update an existing id. Missing or deleted entities return 404.
curl -X POST https://shipdeploy.work/api/v1/entities/update.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","type":"person","data":{"name":"Ada Lovelace","active":true}}'Patch entity data
Apply data patches in order. Type and labels stay unchanged.
curl -X POST https://shipdeploy.work/api/v1/entities/patch.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","patches":[["assoc","active",true],["assoc-in",["profile","email"],"ada@example.com"],["deep-merge",{"profile":{"address":{"city":"Cape Town"}}}],["dissoc","legacy"]]}'Replace labels
Type and data stay unchanged. An empty map clears all labels.
curl -X POST https://shipdeploy.work/api/v1/entities/labels.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","labels":{"region":"za","workflow/status":"active"},"reason":"assigned to active workflow"}'Create multiple entities
Send 1 to 20 entities within 1 MB. By default, all succeed or none are saved. Set transaction to false for independent results.
curl -X POST https://shipdeploy.work/api/v1/entities/batch.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"entities":[{"id":"person-ada","type":"person","data":{"name":"Ada"}},{"type":"person","data":{"name":"Grace"}}]}'curl -X POST https://shipdeploy.work/api/v1/entities/batch.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"transaction":false,"entities":[{"id":"person-ada","type":"person","data":{"name":"Ada"}},{"id":"person-grace","type":"person","data":{"name":"Grace"}}]}'Soft delete
Hide the entity. Keep its history and versions.
curl -X POST https://shipdeploy.work/api/v1/entities/delete.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","mode":"soft"}'Hard delete
Remove the entity. Keep its history and versions.
curl -X POST https://shipdeploy.work/api/v1/entities/delete.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","mode":"hard"}'Evict
Permanently remove the entity and all history.
curl -X POST https://shipdeploy.work/api/v1/entities/evict.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada"}'List history
List change metadata. Deleted entities remain until evicted. No data or diffs.
curl -X POST https://shipdeploy.work/api/v1/entities/history.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","page":1,"page-size":20}'List changes
Same response as history.
curl -X POST https://shipdeploy.work/api/v1/entities/changes.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","page":1,"page-size":20}'Get a version
Get one version snapshot.
curl -X POST https://shipdeploy.work/api/v1/entities/history/version.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","version":2}'Get recent entities by type
Get the latest 20 entities of one type.
curl -X POST https://shipdeploy.work/api/v1/queries/recent-entities-by-type.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"type":"person"}'Inspect one object
Infer fields and types. No key required.
curl -X POST https://shipdeploy.work/api/v1/schema.json \
-H 'content-type: application/json' \
-d '{"object":{"name":"Ada","age":37,"active":true,"tags":["research"]}}'Inspect one stored entity
Infer one stored entity's structure.
curl -X POST https://shipdeploy.work/api/v1/schema/by-entity-id.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada"}'Sample stored entities
See common and uncommon fields in a sample.
curl -X POST https://shipdeploy.work/api/v1/schema/sample-by-type.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"type":"person","sample-size":20}'Configure an entity type
Set display names and infer links from stored ids.
curl -X POST https://shipdeploy.work/api/v1/entity-type-configs.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"type":"person","display-name":"{{name}}","relationships":[{"id":"person-manager","name":"Manager","to-type":"person","cardinality":"many-to-one","source-field":"manager-id"}]}'Link entities
Define a relationship, then link two ids.
curl -X POST https://shipdeploy.work/api/v1/relationship-definitions.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-team","name":"Team member","from-type":"person","to-type":"team","cardinality":"many-to-one"}'curl -X POST https://shipdeploy.work/api/v1/entity-relationships.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"relationship-id":"person-team","from-id":"person-ada","to-id":"team-research","reason":"assigned to research team"}'List or infer links
Read links or create them from configured id fields.
curl -X POST https://shipdeploy.work/api/v1/entity-relationships/by-entity.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada"}'curl -X POST https://shipdeploy.work/api/v1/entity-relationships/infer.json \
-H 'content-type: application/json' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{"id":"person-ada","reason":"inferred from manager-id"}'Use EDN from Clojure
Send and receive native EDN data.
Send content-type: application/edn. Request EDN with accept: application/edn or .edn.
Parse responses with clojure.edn/read-string.
curl -X POST https://shipdeploy.work/api/v1/entities.edn \
-H 'content-type: application/edn' \
-H 'accept: application/edn' \
-H 'x-api-key: replace-with-your-api-key' \
-d '{:id "person-ada" :type "person" :data {:name "Ada" :active true :tags ["research"]}}'(import '[java.net URI]
'[java.net.http HttpClient HttpRequest HttpRequest$BodyPublishers HttpResponse$BodyHandlers])
(require '[clojure.edn :as edn])
(def payload
{:id "person-ada"
:type "person"
:data {:name "Ada" :active true}})
(def response
(.send (HttpClient/newHttpClient)
(-> (HttpRequest/newBuilder (URI/create "https://shipdeploy.work/api/v1/entities.edn"))
(.header "content-type" "application/edn")
(.header "accept" "application/edn")
(.header "x-api-key" "replace-with-your-api-key")
(.POST (HttpRequest$BodyPublishers/ofString (pr-str payload)))
(.build))
(HttpResponse$BodyHandlers/ofString)))
(edn/read-string (.body response))Common responses
Standard HTTP status codes.
Missing or invalid API key.
Read-only API key attempted a write operation.
Route or entity was not found.
Entity id already exists.
Request body exceeded 1 MB.