Skip to content
PacSpace
Talk to us

Dashboard authentication

Request access, register with an approval token, sign in, manage the session, set up MFA, and choose the workspace kind.

All routes on this page live under https://app.pacspace.io/dashboard/auth.

http
POST https://app.pacspace.io/dashboard/auth/request-access

Public routes need no session. Protected routes need the dashboard session cookie (-b pacspace-dashboard-cookies.txt), which signing in sets. A POST, PUT, PATCH, or DELETE that carries the cookie also sends X-Pacspace-CSRF: 1 and Origin: https://app.pacspace.io; without them the answer is 403 and nothing changes.

Each route here takes up to 10 requests a minute from one address, and request access takes 5; past that the answer is 429 RATE_LIMIT_EXCEEDED with retryAfterSeconds. Some refusals here, such as a wrong password, come back with a 2xx status, success: false, and the reason in error, so read success as well as the status.

Request access

PacSpace accounts are approved before a workspace is created. Start with a request-access call. It always gives the same answer, even if the email already has a request.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/request-access \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe",
    "email": "jane@lab.example",
    "organization": "Example Lab",
    "buyerMode": "RECORDS_OPERATOR",
    "useCase": "Record what our agents do in evaluations and in deployment, and share the record with outside evaluators."
  }'

name is up to 100 characters, organization up to 255, and useCase is optional, up to 1000.

Answer

json
{
  "success": true,
  "data": {},
  "message": "Access request received. If approved, PacSpace will send next steps."
}

Register

After approval, PacSpace sends a single-use approval token. It works only for the email it was approved for, and it expires, after 14 days unless PacSpace set another window. Use it to create the account.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/register \
  -c pacspace-dashboard-cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Doe",
    "email": "jane@lab.example",
    "password": "Correct-Horse-42",
    "organization": "Example Lab",
    "buyerMode": "RECORDS_OPERATOR",
    "approvalToken": "APPROVAL_TOKEN"
  }'

A password is 12 to 64 printable ASCII characters, with at least one uppercase letter, one lowercase letter, one number, and one special character. A registration that succeeds signs you in and sets the session cookie, and Sandbox starts setting up for the new workspace (see Environments).

buyerMode is the kind of workspace: RECORDS_OPERATOR for a records workspace. It can be changed under Settings until the first entry is committed, and not after. Without an approved token, or with one that has expired, been used, or was approved for another email, registration answers 403 with { "success": false, "error": "REGISTRATION_REQUIRES_APPROVAL", "statusCode": 403 } and no workspace is created.

Sign in

Sign in with email and password; the answer sets the httpOnly session cookie.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/login \
  -c pacspace-dashboard-cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@lab.example",
    "password": "Correct-Horse-42"
  }'

Answer

json
{
  "success": true,
  "data": {
    "id": "cmw3h8d2q0001s601b4n6c2wd",
    "email": "jane@lab.example",
    "name": "Jane Doe",
    "role": "admin",
    "isSiteAdmin": false,
    "isVerified": true,
    "buyerMode": "RECORDS_OPERATOR",
    "mfaEnabled": false,
    "preferredEnvironment": "sandbox"
  },
  "message": "Login successful"
}

If MFA is on and the request carries no mfaCode, sign-in answers:

json
{
  "success": true,
  "data": {
    "requiresMfa": true,
    "mfaTicket": "..."
  },
  "message": "MFA verification required"
}

Complete an MFA sign-in

The ticket lasts five minutes. code is the 6-digit code from the authenticator app, or a recovery code.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/login/mfa-verify \
  -c pacspace-dashboard-cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "mfaTicket": "MFA_TICKET_FROM_LOGIN",
    "code": "123456"
  }'

You can also send the code with the password, as mfaCode on /login.

Refresh the session

Rotates the httpOnly refresh cookie and issues a new httpOnly access cookie. The request needs no body.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/refresh-token \
  -b pacspace-dashboard-cookies.txt \
  -c pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io"

Sign out

Revokes the refresh cookie and clears both session cookies. The request needs no body.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/logout \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io"

Verify email

The verification email links to a dashboard page that carries the token, and the page sends it here. The token lasts an hour.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/verify \
  -H "Content-Type: application/json" \
  -d '{ "token": "VERIFICATION_TOKEN" }'

Send the verification email again

bash
curl -X POST https://app.pacspace.io/dashboard/auth/resend-verification-email \
  -H "Content-Type: application/json" \
  -d '{ "email": "jane@lab.example" }'

Password recovery

bash
curl -X POST https://app.pacspace.io/dashboard/auth/request-password-reset \
  -H "Content-Type: application/json" \
  -d '{ "email": "jane@lab.example" }'

Set a new password

The reset link's token lasts an hour. The new password follows the same rule as at registration.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "RESET_TOKEN",
    "password": "Battery-Staple-17"
  }'

Change the password while signed in

bash
curl -X POST https://app.pacspace.io/dashboard/auth/change-password \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "Correct-Horse-42",
    "newPassword": "Battery-Staple-17"
  }'

Change email

Ask for the change. A link goes to the new address, and the email stays as it is until the link is confirmed.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/change-email \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io" \
  -H "Content-Type: application/json" \
  -d '{
    "newEmail": "jane.doe@lab.example",
    "currentPassword": "Correct-Horse-42"
  }'

The link opens a dashboard page that sends its token to confirm the change. The token lasts an hour.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/verify-email-change \
  -H "Content-Type: application/json" \
  -d '{ "token": "EMAIL_CHANGE_TOKEN" }'

Multi-factor authentication (MFA)

1) Get the setup secret

bash
curl -X POST https://app.pacspace.io/dashboard/auth/mfa/setup \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io"

Answers the setup material once: secret, otpauthUrl for the authenticator app, recoveryCodes, and mfaEnabled: false.

2) Turn MFA on

code is the 6-digit code the authenticator app shows for the new secret.

bash
curl -X POST https://app.pacspace.io/dashboard/auth/mfa/enable \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io" \
  -H "Content-Type: application/json" \
  -d '{ "code": "123456" }'

3) Turn MFA off

bash
curl -X POST https://app.pacspace.io/dashboard/auth/mfa/disable \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "Correct-Horse-42",
    "code": "123456"
  }'

Profile and preferences

Get the profile

bash
curl https://app.pacspace.io/dashboard/auth/profile \
  -b pacspace-dashboard-cookies.txt

Answers id, email, name, role, tenantId, isVerified, isSiteAdmin, mfaEnabled, preferredEnvironment, and buyerMode, with "Profile retrieved successfully".

Set the preferred environment

bash
curl -X PATCH https://app.pacspace.io/dashboard/auth/preferences \
  -b pacspace-dashboard-cookies.txt \
  -H "X-Pacspace-CSRF: 1" \
  -H "Origin: https://app.pacspace.io" \
  -H "Content-Type: application/json" \
  -d '{ "preferredEnvironment": "sandbox" }'

preferredEnvironment is sandbox or production. It is the environment the dashboard opens in for this person.

Workspace kind

bash
curl https://app.pacspace.io/dashboard/auth/buyer-mode \
  -b pacspace-dashboard-cookies.txt

Answer

json
{
  "success": true,
  "data": {
    "buyerMode": "RECORDS_OPERATOR",
    "locked": false,
    "hasCommittedWrite": false
  }
}

locked turns true once the workspace's first entry is committed. Until then, PATCH the same route with { "buyerMode": "RECORDS_OPERATOR" } to change it; it takes the admin or manager role and answers buyerMode and changed. Once locked, a change is refused with 409 BUYER_MODE_LOCKED: "This choice is fixed once your first record is committed."

Routes

EndpointMethodAuth
/dashboard/auth/request-accessPOSTPublic
/dashboard/auth/registerPOSTPublic, with an approval token
/dashboard/auth/loginPOSTPublic
/dashboard/auth/login/mfa-verifyPOSTPublic, with an MFA ticket
/dashboard/auth/refresh-tokenPOSTRefresh cookie
/dashboard/auth/logoutPOSTRefresh cookie
/dashboard/auth/verifyPOSTPublic, with a token
/dashboard/auth/resend-verification-emailPOSTPublic
/dashboard/auth/request-password-resetPOSTPublic
/dashboard/auth/reset-passwordPOSTPublic, with a token
/dashboard/auth/change-passwordPOSTSession cookie
/dashboard/auth/change-emailPOSTSession cookie
/dashboard/auth/verify-email-changePOSTPublic, with a token
/dashboard/auth/mfa/setupPOSTSession cookie
/dashboard/auth/mfa/enablePOSTSession cookie
/dashboard/auth/mfa/disablePOSTSession cookie
/dashboard/auth/profileGETSession cookie
/dashboard/auth/preferencesPATCHSession cookie
/dashboard/auth/buyer-modeGETSession cookie
/dashboard/auth/buyer-modePATCHSession cookie, admin or manager