{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-api-docs/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Rosterfy API"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"rosterfy-api","__idx":0},"children":["Rosterfy API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Rosterfy REST API lets you read and write the same records the console works"," ","with — people, events, shifts, forms, training, role offers and the rest — so you"," ","can keep another system in step with Rosterfy without anyone re-keying anything."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"where-the-api-lives","__idx":1},"children":["Where the API lives"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every account is reached on its own hostname, the one you sign in on:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"https://<your-account>.rosterfy.com/api/v2\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Accounts on a regional deployment use the domain they sign in on instead of"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rosterfy.com"]},". Whichever it is, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v2"]}," prefix and everything after it is"," ","the same."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"getting-a-token","__idx":2},"children":["Getting a token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every endpoint except the token exchange itself expects an OAuth 2 bearer token:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"Authorization: Bearer <access_token>\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You get one by posting your client credentials and a user's sign-in details to"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /api/v2/oauth/token"]}," — the first operation in the reference. The token"," ","carries exactly that user's access, so use a dedicated integration user rather"," ","than a person's own login: the integration keeps working when people come and"," ","go, and its activity stays distinguishable in the audit trail."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Access tokens last 30 days. The refresh token issued alongside lives longer and"," ","can be exchanged for a new access token by calling the same endpoint again with"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["grant_type=refresh_token"]},". Refresh before the access token lapses rather than"," ","after — once it has expired there is nothing left to refresh."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Treat the access token the way you would treat the password you exchanged for"," ","it. Anything holding it has that user's access for as long as it lives."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"read-these-first","__idx":3},"children":["Read these first"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The guides describe conventions that hold across every endpoint, and they will"," ","save you working them out one endpoint at a time:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-docs/guides/errors"},"children":["Errors and status codes"]}]}," — including why the API"," ","answers ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," where you might expect ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-docs/guides/request-filters"},"children":["Filtering, sorting and pagination"]}]}," — the"," ","query parameters every listing endpoint shares."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-docs/guides/request-options"},"children":["Request options"]}]}," — the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_options"]}," envelope"," ","that changes how a write is carried out."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-docs/guides/rate-limits"},"children":["Rate limits"]}]}," — the two windows that apply, and"," ","what happens when you exceed one."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api-docs/guides/webhooks"},"children":["Webhooks"]}]}," — how to be told about a change instead"," ","of polling for it."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"conventions-worth-knowing-up-front","__idx":4},"children":["Conventions worth knowing up front"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Paths are singular and kebab-case: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v2/user"]},", not ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/api/v2/users"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Query parameters and JSON keys are ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lower_snake_case"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Related records are never included unless you ask for them with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["with"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Listing endpoints share one set of parameters — page, sort, filter, with,"," ","extras — documented per endpoint and explained in full in the guides."]}]}]},"headings":[{"value":"Rosterfy API","id":"rosterfy-api","depth":1},{"value":"Where the API lives","id":"where-the-api-lives","depth":2},{"value":"Getting a token","id":"getting-a-token","depth":2},{"value":"Read these first","id":"read-these-first","depth":2},{"value":"Conventions worth knowing up front","id":"conventions-worth-knowing-up-front","depth":2}],"frontmatter":{"seo":{"title":"Rosterfy API"}},"lastModified":"2026-08-18T06:10:52.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/api-docs","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}