Open HelpDesk API
Run in Postman
  • Getting started
  • Assistants
  • API reference
Information
Tickets
    List ticketsgetCreate a ticketpostRead a ticketgetUpdate a ticketpatchList a ticket's messagesgetAdd a reply or an internal notepostList every file on a ticketget
Contacts
    List contactsgetCreate a contactpostRead a contactgetDelete a contact (GDPR erasure)deleteUpdate a contactpatch
Organizations
    List organizationsgetCreate an organizationpostRead an organizationgetDelete an organizationdeleteUpdate an organizationpatch
Knowledge base
    List categoriesgetList articlesgetCreate an articlepostRead an articlegetDelete an articledeleteUpdate an articlepatch
Attachments
    Download a fileget
Workspace
    List agentsgetList teamsgetList macrosgetList SLA policiesgetList saved viewsgetList custom ticket fieldsgetList tags in usegetList satisfaction responsesget
Mobile
    Mark a ticket readpostSign in on a devicepostStart an SSO sign-in from the appgetFinish an SSO sign-inpostSign this device outpostThe agent this device is signed in asgetTake work, or stop taking workpatchRegister for push notificationspostStop notifying this devicedeleteWhat happened on my tickets while I was awaygetMark everything readpostSearch tickets, contacts, organizations and articlesget
Customer app
    Email a customer their sign-in linkpostHand an emailed sign-in over to the appgetFinish a customer sign-inpostSign this device outpostThe customer this device is signed in asgetThe requests a customer may seegetSubmit a requestpostRead a request and its conversationgetAnswer on your own requestpostRegister for push notificationspostStop notifying this devicedeleteNews about my requestsgetMark everything readpost
Schemas
powered by Zudoku
Open HelpDesk API
Open HelpDesk API

Customer app

What a customer may do with their own requests. A namespace of its own, not the agent routes with a narrower credential.


Email a customer their sign-in link

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/auth/request-link

Customers have no password — the portal signs them in by emailed link, and the app uses the same one. The link lands in a browser, which hands the session to the app through /portal/auth/handoff, so generate a PKCE verifier first and pass its challenge here: it is what the handover code will be bound to.

Always 202. An address with no account, a blocked one and a real one are indistinguishable in the answer — anything else would turn this into a directory of a workspace's customers.

Email a customer their sign-in link › Request Body

email
​string · email · required
code_challenge
​string · minLength: 43 · maxLength: 43 · required

base64url(SHA-256(verifier)).

Email a customer their sign-in link › Responses

The link is on its way, if that address can receive one.

sent
​boolean
email
​string
POST/portal/auth/request-link
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/auth/request-link' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "email": "test@example.com", "code_challenge": "code_challengeaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }'
Example Request Body
{ "email": "test@example.com", "code_challenge": "code_challengeaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }
json
Example Responses
{ "sent": true, "email": "email" }
json
application/json

Hand an emailed sign-in over to the app

GET
https://{workspace}.open-helpdesk.com/api/v1
/portal/auth/handoff

Where the magic link ends up. With the portal cookie the browser just received, it redirects to the app's URL scheme carrying a one-time code. Not called by the app itself — the app waits for the deep link.

Hand an emailed sign-in over to the app › query Parameters

code_challenge
​string · minLength: 43 · maxLength: 43 · required

The challenge the link was built with.

state
​string · maxLength: 128

Hand an emailed sign-in over to the app › Responses

Redirect to openhelpdesk://portal-auth?code=….

No data returned
GET/portal/auth/handoff
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/auth/handoff?code_challenge=<string>'
Example Responses
No example specified for this content type

Finish a customer sign-in

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/auth/exchange

Trades the handover code for a session bound to this phone. Single use, two minutes.

Finish a customer sign-in › Request Body

code
​string · required
code_verifier
​string · minLength: 43 · maxLength: 128 · required
​object

Finish a customer sign-in › Responses

Signed in.

The result of a customer signing in on a device. `token` is shown once — store it in the platform keychain.
PortalSession
token
​string · required
expires_at
​string · date-time · required
​PortalContact · required

A customer, as they may see themselves — never the notes a workspace keeps about them.

session_id
​string · uuid
​object
POST/portal/auth/exchange
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/auth/exchange' \ --request POST \ --header 'Content-Type: application/json' \ --data '{ "code": "code", "code_verifier": "code_verifieraaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "device": { "name": "name", "platform": "ios", "app_version": "app_version" } }'
Example Request Body
{ "code": "code", "code_verifier": "code_verifieraaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "device": { "name": "name", "platform": "ios", "app_version": "app_version" } }
json
Example Responses
{ "token": "ohd_ptl_9d3a…", "session_id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "expires_at": "2024-08-25T15:00:00Z", "contact": { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "email": "test@example.com", "name": "name", "locale": "locale", "organization": { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "name": "name", "shared_tickets": true } }, "workspace": { "slug": "slug", "name": "name" } }
json
application/json

Sign this device out

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/auth/logout

Sign this device out › Responses

Signed out.

No data returned
POST/portal/auth/logout
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/auth/logout' \ --request POST \ --header 'Authorization: Bearer <token>'
Example Responses
No example specified for this content type

The customer this device is signed in as

GET
https://{workspace}.open-helpdesk.com/api/v1
/portal/me

Identity and organization (MC-05). workspace.locale is the language to render in: the product runs one language per workspace, so there is deliberately no per-customer language to write.

The customer this device is signed in as › Responses

Success.

PortalMe
​PortalContact

A customer, as they may see themselves — never the notes a workspace keeps about them.

​object
​object
GET/portal/me
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/me' \ --header 'Authorization: Bearer <token>'
Example Responses
{ "contact": { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "email": "test@example.com", "name": "name", "locale": "locale", "organization": { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "name": "name", "shared_tickets": true } }, "workspace": { "slug": "slug", "name": "name", "locale": "locale" }, "session": { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83" } }
json
application/json

The requests a customer may see

GET
https://{workspace}.open-helpdesk.com/api/v1
/portal/requests

scope=mine is theirs; scope=organization is their company's, and only where that company has ticket sharing turned on. The fifty most recently updated, unpaginated — next_cursor is always null.

The requests a customer may see › query Parameters

scope
​string · enum
Enum values:
mine
organization
Default: mine

The requests a customer may see › Responses

The customer's requests.

​PortalRequest[] · required
next_cursor
​string · required

Pass back as cursor for the next page. Null on the last page.

GET/portal/requests
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/requests' \ --header 'Authorization: Bearer <token>'
Example Responses
{ "data": [ { "number": 4821, "subject": "subject", "status": "new", "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "resolved_at": "2024-08-25T15:00:00Z", "closed_at": "2024-08-25T15:00:00Z", "message_count": 0, "last_message": { "author_type": "agent", "author_name": "author_name", "created_at": "2024-08-25T15:00:00Z" } } ], "next_cursor": "next_cursor" }
json
application/json

Submit a request

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/requests

Files the request on the portal channel and runs the same rules, SLA policies and notifications as the web portal — a request typed on a phone is not a second kind of request.

Submit a request › Request Body

subject
​string · maxLength: 500 · required
body
​string · required
urgency
​string · enum

The customer's own word for it. It stops at high: a field on which anyone can declare their request the most urgent teaches agents to ignore it.

Enum values:
low
normal
high
Default: normal

Submit a request › Responses

The request as filed.

PortalRequestDetail
number
​integer
subject
​string
status
​string
type
​string
created_at
​string · date-time
updated_at
​string · date-time
resolved_at
​string · date-time
closed_at
​string · date-time
​PortalMessage[]
POST/portal/requests
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/requests' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <token>' \ --data '{ "subject": "subject", "body": "body", "urgency": "normal" }'
Example Request Body
{ "subject": "subject", "body": "body", "urgency": "normal" }
json
Example Responses
{ "number": 0, "subject": "subject", "status": "status", "type": "type", "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "resolved_at": "2024-08-25T15:00:00Z", "closed_at": "2024-08-25T15:00:00Z", "messages": [ { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "author_type": "agent", "author_name": "author_name", "body_text": "body_text", "body_html": "body_html", "created_at": "2024-08-25T15:00:00Z", "attachments": [ { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "filename": "filename", "size_bytes": 0, "download_url": "download_url" } ] } ] }
json
application/json

Read a request and its conversation

GET
https://{workspace}.open-helpdesk.com/api/v1
/portal/requests/{number}

Public replies only — internal notes are excluded by the query itself. A request that is not the customer's answers 404, never 403: otherwise the numbers become a way to count a workspace's tickets.

Read a request and its conversation › path Parameters

number
​integer · required

The request number.

Read a request and its conversation › Responses

Success.

PortalRequestDetail
number
​integer
subject
​string
status
​string
type
​string
created_at
​string · date-time
updated_at
​string · date-time
resolved_at
​string · date-time
closed_at
​string · date-time
​PortalMessage[]
GET/portal/requests/{number}
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/requests/:number' \ --header 'Authorization: Bearer <token>'
Example Responses
{ "number": 0, "subject": "subject", "status": "status", "type": "type", "created_at": "2024-08-25T15:00:00Z", "updated_at": "2024-08-25T15:00:00Z", "resolved_at": "2024-08-25T15:00:00Z", "closed_at": "2024-08-25T15:00:00Z", "messages": [ { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "author_type": "agent", "author_name": "author_name", "body_text": "body_text", "body_html": "body_html", "created_at": "2024-08-25T15:00:00Z", "attachments": [ { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "filename": "filename", "size_bytes": 0, "download_url": "download_url" } ] } ] }
json
application/json

Answer on your own request

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/requests/{number}/messages

Only the requester may write; a colleague who can read the company's requests cannot answer in their thread. A reply reopens what was waiting, on hold or resolved.

Answer on your own request › path Parameters

number
​integer · required

The request number.

Answer on your own request › Request Body

body
​string · required

Answer on your own request › Responses

The message as written.

A public reply. Internal notes are never part of this collection.
PortalMessage
id
​string · uuid
author_type
​string · enum
Enum values:
agent
contact
system
author_name
​string
body_text
​string
body_html
​string
created_at
​string · date-time
​object[]
POST/portal/requests/{number}/messages
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/requests/:number/messages' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <token>' \ --data '{ "body": "body" }'
Example Request Body
{ "body": "body" }
json
Example Responses
{ "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "author_type": "agent", "author_name": "author_name", "body_text": "body_text", "body_html": "body_html", "created_at": "2024-08-25T15:00:00Z", "attachments": [ { "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "filename": "filename", "size_bytes": 0, "download_url": "download_url" } ] }
json
application/json

Register for push notifications

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/devices

Upsert on the token, like the agents' registrations.

Register for push notifications › Request Body

push_token
​string · maxLength: 512 · required
platform
​string · enum · required
Enum values:
ios
android
device_name
​string
app_version
​string

Register for push notifications › Responses

Registered.

A push registration. The APNs/FCM token itself is never returned.
PushDevice
id
​string · uuid
platform
​string · enum
Enum values:
ios
android
device_name
​string
app_version
​string
agent_id
​string · uuid
contact_id
​string · uuid
created_at
​string · date-time
last_seen_at
​string · date-time
POST/portal/devices
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/devices' \ --request POST \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <token>' \ --data '{ "push_token": "push_token", "platform": "ios", "device_name": "device_name", "app_version": "app_version" }'
Example Request Body
{ "push_token": "push_token", "platform": "ios", "device_name": "device_name", "app_version": "app_version" }
json
Example Responses
{ "id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "platform": "ios", "device_name": "device_name", "app_version": "app_version", "agent_id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "contact_id": "3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83", "created_at": "2024-08-25T15:00:00Z", "last_seen_at": "2024-08-25T15:00:00Z" }
json
application/json

Stop notifying this device

DELETE
https://{workspace}.open-helpdesk.com/api/v1
/portal/devices/{id}

Stop notifying this device › path Parameters

id
​string · uuid · required

The registration id.

Example: 3f2a1c94-8e5b-4d17-9f60-2c7b1a0d5e83

Stop notifying this device › Responses

Revoked.

No data returned
DELETE/portal/devices/{id}
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/devices/:id' \ --request DELETE \ --header 'Authorization: Bearer <token>'
Example Responses
No example specified for this content type

News about my requests

GET
https://{workspace}.open-helpdesk.com/api/v1
/portal/notifications

Somebody answered, or a request was resolved (MC-04). Nothing about a colleague's request: belonging to an organization that shares its tickets lets someone read them, which is not being notified about them.

News about my requests › Responses

Success.

PortalNotificationFeed
​PortalNotification[] · required
unread_count
​integer · required
read_at
​string · date-time · required
GET/portal/notifications
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/notifications' \ --header 'Authorization: Bearer <token>'
Example Responses
{ "data": [ { "id": "id", "kind": "agent_reply", "request_number": 0, "request_subject": "request_subject", "actor_name": "actor_name", "at": "2024-08-25T15:00:00Z", "read": true } ], "unread_count": 0, "read_at": "2024-08-25T15:00:00Z" }
json
application/json

Mark everything read

POST
https://{workspace}.open-helpdesk.com/api/v1
/portal/notifications/read

Mark everything read › Responses

Success.

ReadReceipt
read_at
​string · date-time
unread_count
​integer
POST/portal/notifications/read
curl 'https://{workspace}.open-helpdesk.com/api/v1/portal/notifications/read' \ --request POST \ --header 'Authorization: Bearer <token>'
Example Responses
{ "read_at": "2024-08-25T15:00:00Z", "unread_count": 0 }
json
application/json

Mobile