Skip to main content
This uses the same Sign-In with Ethereum (SIWE) flow as the original V1 API: request a message, sign it with your wallet, then exchange the signature for a JWT.
1

Get SIWE message

GET /v1/auth/api/siwe returns a message for your wallet to sign.
2

Sign with wallet

Sign the returned message using your wallet’s private key.
3

Verify and get JWT

POST /v1/auth/api/siwe verifies the signature and returns a JWT valid for 24 hours.

Which flow do I use?

Personal auth

Pass wallet only. Use this when the signing wallet belongs to an individual Rise user who already has admin access on one or more teams/companies.

Company/team-scoped auth

Pass wallet + rise_id + impersonate. This is the standard pattern for API integrations: a dedicated wallet, registered as the team/company’s Owner or a delegate, authenticates as a specific manager on that team/company.
Both flows use the same two endpoints and response shapes below — they differ only in which query params you send on the GET step, since those params get embedded as resources inside the message you sign. For the company/team-scoped flow, two identities are checked independently:
  • wallet must be the team/company’s on-chain Owner, or a wallet added as a delegate on that RiseID (see Secondary Wallets for setting one up). This proves the caller is authorized to act for the entity.
  • impersonate must be the email of an existing Rise user who is a manager on that same team — specifically one with the team_admin, team_finance_admin, team_delegate_admin, or team_payment_initiator role. This determines whose identity (and payroll permissions) the resulting JWT carries. It does not need to be the same person as the delegate wallet’s owner.

Get SIWE message

GET /v1/auth/api/siwe
string
required
Wallet address doing the signing.
string
The team or company’s V1 RiseID you’re authenticating against — not a personal user RiseID. Required together with impersonate for the company/team-scoped flow.
string
Email of the manager to authenticate as within that team/company — must be a user with the team_admin, team_finance_admin, team_delegate_admin, or team_payment_initiator role on rise_id. Required together with rise_id.
When rise_id/impersonate are supplied, the returned message embeds them as SIWE resources. Sign that exact message as-is — don’t reconstruct or strip the resources before signing, or verification will fail.

Verify SIWE signature

POST /v1/auth/api/siwe
string
required
Wallet address of the user.
string
required
The original SIWE message returned by the GET step.
string
required
The signature produced by signing message with the wallet’s private key.
Use the returned token as a bearer token on every other request:

Creating the signature and token in code

Personal authriseIdAuth configures the client to authenticate (and re-authenticate on expiry) automatically. riseId here must be the individual user’s own personal RiseID, not a team/company one:
Company/team-scoped authriseIdAuth’s automatic flow doesn’t apply here (it’s V2-only and expects a personal RiseID). Call getSiwe/verifySiwe yourself, passing the team/company’s rise_id, then hand the resulting token to the client with updateToken:

Manual HTTP (no SDK)

For the company/team-scoped flow, add rise_id/impersonate to the GET query string:
The rest of the flow (sign message, POST it back with wallet/message/signature) is identical — rise_id/impersonate travel embedded in message, not as separate POST fields.
Never expose WALLET_PRIVATE_KEY/PRIVATE_KEY in client-side code. Sign server-side, or use a dedicated secondary wallet scoped to API access.

Errors

Still stuck? See Troubleshooting.
If your account hasn’t finished migrating yet, these calls are transparently forwarded to the original V1 backend — no behavior change on your end.