Skip to main content
This walkthrough goes from “Daysync just approved my application” to “I’ve called the API as a real user.” Plan for ~15 minutes.

Before you start

You should have:
  • x-api-key (dk_live_…) and x-api-secret (ds_…) for your app — these double as your OAuth client ID / client secret (see Authentication and Apply for API Access)
  • A registered redirect URI. For this walkthrough we’ll use Postman’s callback — add https://oauth.pstmn.io/v1/callback to your app’s Redirect URIs in the Integrations Portal first (it takes effect instantly)
  • A real Daysync user account (sign up at app.daysync.com if you don’t have one)
  • Terminal access with curl, jq, and openssl
Export everything as shell variables now — every step below references them. Your API key/secret are the OAuth client credentials; there is no separate shared client.
export DAYSYNC_API_KEY="dk_live_…"
export DAYSYNC_API_SECRET="ds_…"
export DAYSYNC_REDIRECT_URI="https://oauth.pstmn.io/v1/callback"

Step 1 — Generate a PKCE pair

PKCE (S256) is required on every authorization. Generate a code_verifier and its code_challenge:
export DAYSYNC_CODE_VERIFIER=$(openssl rand -base64 96 | tr -d '\n=+/' | cut -c1-64)
export DAYSYNC_CODE_CHALLENGE=$(printf '%s' "$DAYSYNC_CODE_VERIFIER" \
  | openssl dgst -sha256 -binary | openssl base64 | tr -d '=\n' | tr '/+' '_-')
echo "verifier=$DAYSYNC_CODE_VERIFIER"
echo "challenge=$DAYSYNC_CODE_CHALLENGE"
Keep the verifier for Step 3; the challenge goes in the authorize URL below.

Step 2 — Get a user authorization code

Open this URL in a browser (the line breaks are for reading; remove them before pasting):
https://integrations.daysync.com/authorize
  ?response_type=code
  &client_id=YOUR_API_KEY
  &redirect_uri=https://oauth.pstmn.io/v1/callback
  &scope=openid+email+daysync-api/tours.read+daysync-api/organization.read
  &state=xyz123
  &code_challenge=YOUR_CODE_CHALLENGE
  &code_challenge_method=S256
You’ll sign in with your Daysync account (the portal’s normal login), then see a consent screen naming your app and the requested permissions. After you approve, the browser redirects to:
https://oauth.pstmn.io/v1/callback?code=ABCDEFG…&state=xyz123
Copy the code value out of the URL bar.
export DAYSYNC_AUTH_CODE="ABCDEFG…"
Authorization codes expire in ~5 minutes and are single-use. If Step 3 fails with invalid_grant, redo Step 1–2 to get a fresh code (a fresh PKCE pair too).

Step 3 — Exchange the code for tokens

Authenticate the client with HTTP Basic auth (-u) using your API key and secret, and include the PKCE code_verifier:
curl -sS -X POST https://integrations.daysync.com/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$DAYSYNC_API_KEY:$DAYSYNC_API_SECRET" \
  -d "grant_type=authorization_code" \
  -d "code=$DAYSYNC_AUTH_CODE" \
  -d "redirect_uri=$DAYSYNC_REDIRECT_URI" \
  -d "code_verifier=$DAYSYNC_CODE_VERIFIER" | jq .
Response:
{
  "access_token": "eyJraWQ…",
  "refresh_token": "eyJjdHk…",
  "token_type": "Bearer",
  "expires_in": 3412,
  "scope": "daysync-api/tours.read daysync-api/organization.read"
}
Capture the tokens. Treat scope as the authoritative record of what the user consented to, and expires_in as the token’s real remaining life (it can be less than 3600 — refresh when it nears zero):
export DAYSYNC_ACCESS_TOKEN="eyJraWQ…"
export DAYSYNC_REFRESH_TOKEN="eyJjdHk…"

Step 4 — List the user’s organizations

This is the canonical first API call. Every integration starts here because every other resource is scoped to an organization.
curl -sS "https://integration.daysync.com/v1/organizations" \
  -H "x-api-key: $DAYSYNC_API_KEY" \
  -H "x-api-secret: $DAYSYNC_API_SECRET" \
  -H "Authorization: Bearer $DAYSYNC_ACCESS_TOKEN" | jq .
Response (abbreviated — see the Organizations endpoint reference for the full field list):
{
  "status": true,
  "message": "Success",
  "data": [
    {
      "id": "5f8c9b2a-…",
      "name": "Acme Touring",
      "loggedInUserRole": { "id": 1, "name": "org_admin" },
      "orgUserCount": 12,
      "is_trial": false
    }
  ]
}
Capture an org_id for the next step:
export DAYSYNC_ORG_ID="5f8c9b2a-…"

Step 5 — List tours for that organization

curl -sS "https://integration.daysync.com/v1/tours?org_id=$DAYSYNC_ORG_ID" \
  -H "x-api-key: $DAYSYNC_API_KEY" \
  -H "x-api-secret: $DAYSYNC_API_SECRET" \
  -H "Authorization: Bearer $DAYSYNC_ACCESS_TOKEN" | jq .
You should see the tours that user has access to. If you get an empty array, sign in at app.daysync.com and create a tour, then re-run.

Step 6 — Refresh the access token

Access tokens expire in ≈60 minutes. Refresh tokens last 30 days. Refresh with the same client credentials — no PKCE needed on refresh:
curl -sS -X POST https://integrations.daysync.com/api/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$DAYSYNC_API_KEY:$DAYSYNC_API_SECRET" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=$DAYSYNC_REFRESH_TOKEN" | jq .
The response has the same shape as Step 3 (without scope). Keep reusing the refresh token until it expires after 30 days; when it does, the call fails with 400 invalid_grant and you send the user through the authorization flow again.

Going to production

This walkthrough used Postman’s callback URL (https://oauth.pstmn.io/v1/callback) for the OAuth flow. You’ve validated that your credentials work — but you haven’t tested your own production OAuth flow yet.Before going live: add your own callback URL under Redirect URIs on your app in the Integrations Portal (see Callback URLs), then re-run Step 2 with redirect_uri=<your-registered-callback> to exercise the same flow your real users will go through.

What’s next

Common Workflows

End-to-end recipes — full tour setup, sync loops, guest list management.

Endpoint Reference

Every endpoint with request bodies, response shapes, and required scopes.

Scopes

Which scopes you need to request for each endpoint.

Errors

Every HTTP status code and machine-readable error code.

Trouble?

Authorization codes expire fast (~5 minutes) and are single-use, and the code_verifier must match the code_challenge you sent in Step 2. Redo Step 1–2 for a fresh PKCE pair and code, then run Step 3 promptly.
Your authorize URL is missing code_challenge or code_challenge_method=S256. PKCE is mandatory — generate the pair in Step 1 and include both parameters.
Most likely missing or wrong x-api-key / x-api-secret. Confirm the values from your provisioning email, paying attention to trailing whitespace.
Your partner credentials weren’t issued with the scope this endpoint requires. Cross-reference the endpoint’s required scope on Scopes & Permissions, then email support@daysync.com to request additional scopes.
The redirect_uri in your authorize URL isn’t on your app’s allowlist. Add it under Redirect URIs in the Integrations Portal — it takes effect immediately. See Callback URLs for the exact-match rules.