@riseworks/riseworks-sdk 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -0
- package/ai-skills/README.md +28 -0
- package/ai-skills/STANDARDS.md +66 -0
- package/ai-skills/references/API_WORKFLOWS.md +200 -0
- package/ai-skills/references/TYPES.md +190 -0
- package/ai-skills/rise-auth-and-setup/README.md +14 -0
- package/ai-skills/rise-auth-and-setup/SKILL.md +57 -0
- package/ai-skills/rise-auth-and-setup/metadata.json +12 -0
- package/ai-skills/rise-auth-and-setup/references/SETUP_PATTERNS.md +26 -0
- package/ai-skills/rise-debugging-and-errors/SKILL.md +51 -0
- package/ai-skills/rise-payments-workflows/README.md +19 -0
- package/ai-skills/rise-payments-workflows/SKILL.md +109 -0
- package/ai-skills/rise-payments-workflows/metadata.json +12 -0
- package/ai-skills/rise-payments-workflows/references/PAYMENT_PATTERNS.md +36 -0
- package/ai-skills/rise-sdk-integration/README.md +25 -0
- package/ai-skills/rise-sdk-integration/SKILL.md +130 -0
- package/ai-skills/rise-sdk-integration/metadata.json +12 -0
- package/ai-skills/rise-sdk-integration/references/PATTERNS.md +28 -0
- package/ai-skills/rise-security-and-approvals/SKILL.md +33 -0
- package/ai-skills/rise-teams-and-invites/README.md +13 -0
- package/ai-skills/rise-teams-and-invites/SKILL.md +66 -0
- package/ai-skills/rise-teams-and-invites/metadata.json +12 -0
- package/ai-skills/rise-teams-and-invites/references/TEAM_PATTERNS.md +25 -0
- package/ai-skills/rise-v1-migration/README.md +22 -0
- package/ai-skills/rise-v1-migration/SKILL.md +184 -0
- package/ai-skills/rise-v1-migration/metadata.json +13 -0
- package/ai-skills/rise-v1-migration/references/ENDPOINT_MAPPINGS.md +72 -0
- package/ai-skills/rise-v1-migration/references/MIGRATION_PATTERNS.md +66 -0
- package/ai-skills/rise-webhooks/README.md +41 -0
- package/ai-skills/rise-webhooks/SKILL.md +143 -0
- package/ai-skills/rise-webhooks/metadata.json +13 -0
- package/ai-skills/rise-webhooks/references/HANDLER.md +60 -0
- package/ai-skills/rise-webhooks/references/REGISTRATION.md +113 -0
- package/dist/index.cjs +1406 -0
- package/dist/index.d.cts +6865 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +6865 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1383 -0
- package/package.json +87 -0
- package/scripts/add-skills.mjs +158 -0
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Rise SDK
|
|
2
|
+
|
|
3
|
+
Official TypeScript/JavaScript SDK for Rise B2B integrations.
|
|
4
|
+
|
|
5
|
+
It includes:
|
|
6
|
+
- A typed API client for B2B and `v2` endpoints
|
|
7
|
+
- Claude-style AI coding skills you can copy into `.claude/skills/`
|
|
8
|
+
- Built-in webhook validation
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install riseworks-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { RiseApiClient } from 'riseworks-sdk'
|
|
20
|
+
|
|
21
|
+
const client = new RiseApiClient({
|
|
22
|
+
environment: 'stg',
|
|
23
|
+
jwtToken: process.env.RISE_JWT_TOKEN!,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const me = await client.me.get()
|
|
27
|
+
const organizations = await client.user.getOrganizations()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## AI Coding Skills
|
|
31
|
+
|
|
32
|
+
The npm package ships reusable Claude-style `SKILL.md` files for coding assistants.
|
|
33
|
+
|
|
34
|
+
**Add skills from the CLI (no copy-paste):**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Add all skills to all supported agents (default)
|
|
38
|
+
npx riseworks-sdk add-skills
|
|
39
|
+
|
|
40
|
+
# Add to one agent only
|
|
41
|
+
npx riseworks-sdk add-skills --agent cursor rise-sdk-integration rise-webhooks
|
|
42
|
+
|
|
43
|
+
# List available skills and supported agents
|
|
44
|
+
npx riseworks-sdk add-skills --list
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or copy manually from `node_modules/riseworks-sdk/ai-skills/` into `.claude/skills/`, `.cursor/skills/`, etc.
|
|
48
|
+
|
|
49
|
+
Available skills:
|
|
50
|
+
|
|
51
|
+
- `rise-sdk-integration`
|
|
52
|
+
- `rise-v1-migration`
|
|
53
|
+
- `rise-payments-workflows`
|
|
54
|
+
- `rise-webhooks`
|
|
55
|
+
- `rise-teams-and-invites`
|
|
56
|
+
- `rise-auth-and-setup`
|
|
57
|
+
- `rise-security-and-approvals`
|
|
58
|
+
- `rise-debugging-and-errors`
|
|
59
|
+
|
|
60
|
+
Use these when you want Claude Code or a similar coding assistant to write better Rise integration code.
|
|
61
|
+
|
|
62
|
+
## Low-Level API Groups
|
|
63
|
+
|
|
64
|
+
The lower-level client remains available for direct endpoint access.
|
|
65
|
+
|
|
66
|
+
- `client.auth`
|
|
67
|
+
- `client.webhooks`
|
|
68
|
+
- `client.company`
|
|
69
|
+
- `client.organizations`
|
|
70
|
+
- `client.entityBalance`
|
|
71
|
+
- `client.invites`
|
|
72
|
+
- `client.me`
|
|
73
|
+
- `client.payments`
|
|
74
|
+
- `client.billPay`
|
|
75
|
+
- `client.payroll`
|
|
76
|
+
- `client.team`
|
|
77
|
+
- `client.teams`
|
|
78
|
+
- `client.user`
|
|
79
|
+
|
|
80
|
+
Withdrawals are not part of the SDK, and `client.company` / `client.organizations` are read-only: those endpoints require reCAPTCHA verification headers that only a browser session can produce, so they cannot be called server-to-server. Use the Rise dashboard for withdrawals and company profile changes.
|
|
81
|
+
|
|
82
|
+
Every `POST`/`PUT` request automatically carries a fresh `x-idempotency-key` header. Pass your own key to `payments.prepare/create/execute`, `getPaymentTypedData`, `executePaymentWithSignedData`, or `sendPayment` (as `idempotencyKey`) when you want retries of the same logical operation deduplicated on your key instead.
|
|
83
|
+
|
|
84
|
+
## Branded ID types
|
|
85
|
+
|
|
86
|
+
The SDK exports branded nanoid types for API params and responses. Use them when you have a plain `string` from a response and need to pass it to another method:
|
|
87
|
+
|
|
88
|
+
| Type | Use case |
|
|
89
|
+
|------|----------|
|
|
90
|
+
| `TeamNanoid` | `payments.get()`, `teams.get()`, `teams.getUsers()`, `billPay.*`, payroll, invites |
|
|
91
|
+
| `UserNanoid` | `teams.getMemberSettings()`, company members |
|
|
92
|
+
| `CompanyNanoid` | `teams.create()`, company APIs, webhooks |
|
|
93
|
+
| `WithdrawAccountNanoid` | Typing withdraw-account ids in webhook event payloads |
|
|
94
|
+
| `WebhookEndpointNanoid` | `webhooks.get()`, `webhooks.update()`, `webhooks.test()` |
|
|
95
|
+
| `WebhookDeliveryNanoid` | `webhooks.retryDelivery()`, delivery history |
|
|
96
|
+
| `InviteNanoid` | Invite execute/list flows |
|
|
97
|
+
| `TransactionNanoid` | Typing payment response `transaction` fields |
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import {
|
|
101
|
+
RiseApiClient,
|
|
102
|
+
type TeamNanoid,
|
|
103
|
+
type UserNanoid,
|
|
104
|
+
type CompanyNanoid,
|
|
105
|
+
type WithdrawAccountNanoid,
|
|
106
|
+
type WebhookEndpointNanoid,
|
|
107
|
+
type WebhookDeliveryNanoid,
|
|
108
|
+
type InviteNanoid,
|
|
109
|
+
type TransactionNanoid,
|
|
110
|
+
} from 'riseworks-sdk'
|
|
111
|
+
|
|
112
|
+
const client = new RiseApiClient({ environment: 'stg', jwtToken: '…' })
|
|
113
|
+
const { data } = await client.user.getTeams()
|
|
114
|
+
const teamNanoid = data?.teams?.[0]?.nanoid // string
|
|
115
|
+
|
|
116
|
+
await client.payments.get({
|
|
117
|
+
team_nanoid: teamNanoid as TeamNanoid,
|
|
118
|
+
state: 'all',
|
|
119
|
+
query_type: 'payable',
|
|
120
|
+
start_date: new Date(),
|
|
121
|
+
end_date: new Date(),
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Examples
|
|
126
|
+
|
|
127
|
+
### Teams
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const team = await client.teams.get({ team_nanoid: 'te_123' })
|
|
131
|
+
|
|
132
|
+
await client.teams.update(
|
|
133
|
+
{ team_nanoid: 'te_123' },
|
|
134
|
+
{ name: 'Finance Ops' },
|
|
135
|
+
)
|
|
136
|
+
const members = await client.teams.getUsers({ team_nanoid: 'te_123' })
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Bill Pay
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
await client.billPay.createRecipient(
|
|
143
|
+
{ team_nanoid: 'te_123' },
|
|
144
|
+
{ email: 'vendor@example.com' },
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
const payment = await client.billPay.sendInstantPayment({
|
|
148
|
+
from: 'te_123',
|
|
149
|
+
amount_cents: 125000,
|
|
150
|
+
currency_symbol: 'USD',
|
|
151
|
+
external_recipient_email: 'vendor@example.com',
|
|
152
|
+
payment_data: {
|
|
153
|
+
role_description: 'Design work',
|
|
154
|
+
invoice_description: 'Invoice INV-2026-001',
|
|
155
|
+
services_description: 'Landing page design',
|
|
156
|
+
payment_details: 'Net 15',
|
|
157
|
+
rise_sow: false,
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Treasury
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
const balance = await client.entityBalance.get({
|
|
166
|
+
nanoid: 'te_123',
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Batch payments
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const result = await client.payments.sendPayment({
|
|
174
|
+
from: 'te_123' as TeamNanoid,
|
|
175
|
+
to: [{ to: 'us_123' as UserNanoid, amount_cents: 50000, currency_symbol: 'USD' }],
|
|
176
|
+
pay_now: true,
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
console.log(result.data.transaction)
|
|
180
|
+
// Recipients the server skipped or flagged as recently paid are surfaced —
|
|
181
|
+
// check them instead of assuming every recipient in `to` was paid.
|
|
182
|
+
console.log(result.failed_payments)
|
|
183
|
+
console.log(result.duplicates)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Before signing, `sendPayment` verifies the server-provided typed data against your request (expected chain id for the environment, payment count, max per-payment amount) and throws instead of signing anything broader than what you asked for.
|
|
187
|
+
|
|
188
|
+
### Webhooks
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import express from 'express'
|
|
192
|
+
import { WebhookValidator } from 'riseworks-sdk'
|
|
193
|
+
|
|
194
|
+
const app = express()
|
|
195
|
+
const validator = new WebhookValidator(process.env.RISE_WEBHOOK_SECRET!)
|
|
196
|
+
|
|
197
|
+
app.post('/rise-webhooks', express.raw({ type: 'application/json' }), (req, res) => {
|
|
198
|
+
try {
|
|
199
|
+
const event = validator.validateEvent(
|
|
200
|
+
req.body,
|
|
201
|
+
req.headers['x-rise-signature'] as string,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
console.log(event.event_type)
|
|
205
|
+
res.status(200).json({ received: true })
|
|
206
|
+
} catch (error) {
|
|
207
|
+
res.status(400).json({
|
|
208
|
+
error: error instanceof Error ? error.message : 'Webhook validation failed',
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Exports
|
|
215
|
+
|
|
216
|
+
The package exports:
|
|
217
|
+
- `RiseApiClient`
|
|
218
|
+
- `WebhookValidator`
|
|
219
|
+
- Webhook event types
|
|
220
|
+
- Generated API request/response types
|
|
221
|
+
|
|
222
|
+
## Authentication
|
|
223
|
+
|
|
224
|
+
You can authenticate with either:
|
|
225
|
+
- `jwtToken`
|
|
226
|
+
- `riseIdAuth` for automatic SIWE-based JWT generation and refresh
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
const client = new RiseApiClient({
|
|
230
|
+
environment: 'prod',
|
|
231
|
+
riseIdAuth: {
|
|
232
|
+
riseId: process.env.RISE_ID!,
|
|
233
|
+
privateKey: process.env.RISE_PRIVATE_KEY!,
|
|
234
|
+
},
|
|
235
|
+
})
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Rise AI Coding Skills
|
|
2
|
+
|
|
3
|
+
This package ships reusable `SKILL.md` files (Agent Skills format) for AI-assisted Rise SDK integrations. The same skills work across **Claude Code, Cursor, Windsurf, and Codex**. Skills describe the SDK at a point in time; the **installed SDK source is the source of truth** for current methods, types, and behavior—agents are instructed to read the SDK code when implementing.
|
|
4
|
+
|
|
5
|
+
Skills live directly under `ai-skills/` (e.g. `ai-skills/rise-sdk-integration/SKILL.md`). The format is agent-agnostic, so the CLI copies that content into each agent’s folder (`.claude/skills`, `.cursor/skills`, etc.).
|
|
6
|
+
|
|
7
|
+
**Add skills via CLI:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx riseworks-sdk add-skills # add all skills to all agents (default)
|
|
11
|
+
npx riseworks-sdk add-skills --agent cursor rise-sdk-integration rise-webhooks
|
|
12
|
+
npx riseworks-sdk add-skills --list # list skills and supported agents
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or copy from `node_modules/riseworks-sdk/ai-skills/` into your project's agent skills directory (e.g. `.claude/skills/`, `.cursor/skills/`).
|
|
16
|
+
|
|
17
|
+
**Reference:** `ai-skills/references/TYPES.md` — TypeScript types (webhook events, request/response shapes, nanoids). Copied with skills when using the CLI so skills can link to `../references/TYPES.md`.
|
|
18
|
+
|
|
19
|
+
Available skills:
|
|
20
|
+
|
|
21
|
+
- `rise-sdk-integration`
|
|
22
|
+
- `rise-v1-migration`
|
|
23
|
+
- `rise-payments-workflows`
|
|
24
|
+
- `rise-webhooks`
|
|
25
|
+
- `rise-teams-and-invites`
|
|
26
|
+
- `rise-auth-and-setup`
|
|
27
|
+
- `rise-security-and-approvals`
|
|
28
|
+
- `rise-debugging-and-errors`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Skill authoring standards (reference)
|
|
2
|
+
|
|
3
|
+
This package follows the [Agent Skills](https://agentskills.io/specification) format and best practices so skills trigger reliably and produce good output.
|
|
4
|
+
|
|
5
|
+
## Frontmatter (required)
|
|
6
|
+
|
|
7
|
+
- **name**: Max 64 chars, lowercase letters, numbers, hyphens only. Must match the skill directory name.
|
|
8
|
+
- **description**: Max 1024 chars. Primary trigger for agents—include **what** the skill does and **when** to use it. Use third person or imperative (“Use this skill when…”). Add keywords users might say (e.g. “payments”, “migration”, “webhooks”).
|
|
9
|
+
|
|
10
|
+
Optional fields we can use:
|
|
11
|
+
|
|
12
|
+
- **compatibility**: Short note on environment (e.g. “Node.js, TypeScript” or “Claude Code, Cursor, Windsurf, Codex”).
|
|
13
|
+
- **metadata**: e.g. `author`, `version` for traceability.
|
|
14
|
+
|
|
15
|
+
## Body structure (recommended by spec)
|
|
16
|
+
|
|
17
|
+
- **Step-by-step instructions** where the task has a clear sequence.
|
|
18
|
+
- **Common edge cases** (what can go wrong, what to validate).
|
|
19
|
+
- **Examples** of inputs and outputs (or minimal code snippets) so the agent can mirror real usage.
|
|
20
|
+
- **When not to use** (boundaries) so the skill does not trigger on unrelated tasks.
|
|
21
|
+
|
|
22
|
+
## Conciseness (Claude best practices)
|
|
23
|
+
|
|
24
|
+
- Only include what the agent does not already know. Omit generic explanations.
|
|
25
|
+
- Keep the main `SKILL.md` under ~500 lines. Move long reference material to `references/` and link from the body.
|
|
26
|
+
- Prefer one level of reference (e.g. `references/REFERENCE.md`) rather than deep chains.
|
|
27
|
+
|
|
28
|
+
## Progressive disclosure
|
|
29
|
+
|
|
30
|
+
- Agents load only **name** and **description** at discovery (~100 tokens).
|
|
31
|
+
- When the task matches, they load the full **SKILL.md** (aim for <5000 tokens).
|
|
32
|
+
- Put extra docs in `references/` or `scripts/` and reference them so they are loaded only when needed.
|
|
33
|
+
|
|
34
|
+
## Optional authoring files
|
|
35
|
+
|
|
36
|
+
We can also keep extra authoring and human-facing files in each skill directory when they add value:
|
|
37
|
+
|
|
38
|
+
- **`README.md`**: short human summary of the skill, its scope, and file layout.
|
|
39
|
+
- **`metadata.json`**: version, domain, references, and authoring metadata for tooling and maintainers.
|
|
40
|
+
- **`references/*.md`**: detailed implementation guidance for agents to load on demand.
|
|
41
|
+
|
|
42
|
+
Important:
|
|
43
|
+
|
|
44
|
+
- `SKILL.md` remains the **agent-facing compiled document** and should stay concise.
|
|
45
|
+
- `README.md` and `metadata.json` help maintainers and future tooling, but should not replace `SKILL.md`.
|
|
46
|
+
- Prefer adding support files only where they improve output quality materially; avoid adding boilerplate to every skill directory without a clear use.
|
|
47
|
+
|
|
48
|
+
## Triggering (optimizing descriptions)
|
|
49
|
+
|
|
50
|
+
- Describe **user intent** and **context**, not internal implementation.
|
|
51
|
+
- Include both explicit triggers (“when the user says X”) and implicit ones (“even if they don’t say ‘Rise SDK’”).
|
|
52
|
+
- Test with ~20 eval queries (10 should-trigger, 10 should-not-trigger) and refine the description so it does not over- or under-trigger.
|
|
53
|
+
|
|
54
|
+
## SDK as source of truth
|
|
55
|
+
|
|
56
|
+
- Skills document the SDK at a point in time and may not reflect the latest API. **Include a note in SDK-related skills** that agents should always read the installed SDK code (e.g. `node_modules/riseworks-sdk`) for current methods, types, and behavior—the SDK may have new functions or types that are not yet described in the skills.
|
|
57
|
+
|
|
58
|
+
## Documentation
|
|
59
|
+
|
|
60
|
+
- Point to the official **Rise B2B API docs** ([https://v2-docs.riseworks.io/](https://v2-docs.riseworks.io/)) in a "Documentation" section when it helps: Quickstart, Authentication, SDK, Webhooks, API Reference. That way the agent can suggest the right guide or reference instead of duplicating content in the skill.
|
|
61
|
+
|
|
62
|
+
## Validation
|
|
63
|
+
|
|
64
|
+
- Ensure `name` matches the directory and fits the spec (length, characters).
|
|
65
|
+
- Keep `description` under 1024 characters.
|
|
66
|
+
- You can validate with: `skills-ref validate ./skill-name` (from [agentskills/agentskills](https://github.com/agentskills/agentskills)).
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Rise SDK API workflows
|
|
2
|
+
|
|
3
|
+
Use this reference when the user is building application code with
|
|
4
|
+
`riseworks-sdk` and needs the actual SDK method flow, not just type names.
|
|
5
|
+
|
|
6
|
+
## Default approach
|
|
7
|
+
|
|
8
|
+
- Start by identifying the entity the user already has: company, team, user, or
|
|
9
|
+
withdraw account.
|
|
10
|
+
- If they do not have the required nanoid yet, generate discovery calls first.
|
|
11
|
+
- Prefer the SDK method that directly matches the requested workflow.
|
|
12
|
+
- Use exported request/response types instead of anonymous object shapes.
|
|
13
|
+
|
|
14
|
+
## Common discovery flows
|
|
15
|
+
|
|
16
|
+
### Auth bootstrap
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const client = new RiseApiClient({
|
|
20
|
+
environment: 'stg',
|
|
21
|
+
jwtToken,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const me = await client.me.get()
|
|
25
|
+
const teams = await client.user.getTeams()
|
|
26
|
+
const orgs = await client.user.getOrganizations()
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use this when the user needs current-user, company, or initial team/company
|
|
30
|
+
context.
|
|
31
|
+
|
|
32
|
+
### Team and company discovery
|
|
33
|
+
|
|
34
|
+
- `client.user.getTeams()` — first stop when a payment or member operation needs
|
|
35
|
+
a `team_nanoid`
|
|
36
|
+
- `client.user.getOrganizations()` — first stop when company-scoped operations
|
|
37
|
+
need a `company_nanoid`
|
|
38
|
+
- `client.company.getUsers({ nanoid })` — get company users once company context
|
|
39
|
+
is known
|
|
40
|
+
- `client.teams.getUsers({ team_nanoid })` — get payees or members for a team
|
|
41
|
+
|
|
42
|
+
## Teams workflows
|
|
43
|
+
|
|
44
|
+
### Team CRUD
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const created = await client.teams.create(body)
|
|
48
|
+
const team = await client.teams.get({ team_nanoid })
|
|
49
|
+
await client.teams.update({ team_nanoid }, body)
|
|
50
|
+
await client.teams.delete({ team_nanoid })
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Team settings and members
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const settings = await client.teams.getSettings({ team_nanoid })
|
|
57
|
+
await client.teams.updateSettings({ team_nanoid }, body)
|
|
58
|
+
|
|
59
|
+
const users = await client.teams.getUsers({ team_nanoid })
|
|
60
|
+
const member = await client.teams.getMemberSummary({ team_nanoid, user_nanoid })
|
|
61
|
+
await client.teams.removeMember({ team_nanoid, user_nanoid })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Invite workflows
|
|
65
|
+
|
|
66
|
+
### Regular employee/contractor invites
|
|
67
|
+
|
|
68
|
+
No signing required:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await client.invites.send({
|
|
72
|
+
nanoid: companyOrTeamNanoid,
|
|
73
|
+
invites: [{ email, role }],
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Manager invites
|
|
78
|
+
|
|
79
|
+
Automatic signing requires `riseIdAuth` or `privateKey`:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
await client.invites.sendManagerInvite({
|
|
83
|
+
nanoid,
|
|
84
|
+
emails,
|
|
85
|
+
role,
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Manual flow:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const typed = await client.invites.getManagerInviteTypedData(data)
|
|
93
|
+
// sign typed.data.typed_data
|
|
94
|
+
await client.invites.executeManagerInviteWithSignedData(dataWithSignature)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Payment workflows
|
|
98
|
+
|
|
99
|
+
### Query payments
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const payments = await client.payments.get({
|
|
103
|
+
team_nanoid,
|
|
104
|
+
state: 'all',
|
|
105
|
+
query_type: 'payable',
|
|
106
|
+
start_date: new Date(start),
|
|
107
|
+
end_date: new Date(end),
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Use `team_nanoid` from `client.user.getTeams()` when the user does not already
|
|
112
|
+
have one.
|
|
113
|
+
|
|
114
|
+
### Internal Rise payments
|
|
115
|
+
|
|
116
|
+
Automatic flow:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
await client.payments.sendPayment({
|
|
120
|
+
from: teamNanoid,
|
|
121
|
+
to: [{ to: userNanoid, amount_cents: 10000, currency_symbol: 'USD' }],
|
|
122
|
+
pay_now: true,
|
|
123
|
+
network: 'arbitrum',
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Manual flow — the execute step takes the payment group id from the signed data,
|
|
128
|
+
so the two calls must use **different** idempotency keys (a shared key collides
|
|
129
|
+
with the 3s request-dedup window). Omitting the key lets each call generate its
|
|
130
|
+
own:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const typed = await client.payments.getPaymentTypedData(body)
|
|
134
|
+
// sign typed.data.typed_data
|
|
135
|
+
await client.payments.executePaymentWithSignedData(bodyWithSignature)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`sendPayment()` does the same end to end.
|
|
139
|
+
|
|
140
|
+
Safe retries: keys are per call — never share one key between the prepare
|
|
141
|
+
(POST) and the execute (PUT). When retrying the *same* call, do the opposite:
|
|
142
|
+
pass an explicit `idempotencyKey`, reuse that exact key on the retry, and wait
|
|
143
|
+
about 3 seconds between attempts. The server dedups on the key and returns the
|
|
144
|
+
same transaction; a 409 "Duplicate request" within the window means the first
|
|
145
|
+
attempt is still processing. This applies to prepare and execute alike. Set
|
|
146
|
+
`external_id` on each payment as the durable guard — it is unique per payer
|
|
147
|
+
team, so a duplicate submission is rejected rather than paid twice.
|
|
148
|
+
|
|
149
|
+
## Bill pay workflows
|
|
150
|
+
|
|
151
|
+
### External recipients
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
await client.billPay.createRecipient(
|
|
155
|
+
{ team_nanoid },
|
|
156
|
+
{ email: 'vendor@example.com' },
|
|
157
|
+
)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Instant external payment
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
await client.billPay.sendInstantPayment({
|
|
164
|
+
from: teamNanoid,
|
|
165
|
+
amount_cents: 10000,
|
|
166
|
+
currency_symbol: 'USD',
|
|
167
|
+
network: 'arbitrum',
|
|
168
|
+
external_recipient_email: 'vendor@example.com',
|
|
169
|
+
payment_data: {
|
|
170
|
+
role_description: 'Vendor',
|
|
171
|
+
invoice_description: 'March invoice',
|
|
172
|
+
rise_sow: false,
|
|
173
|
+
},
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Balance and withdrawal workflows
|
|
178
|
+
|
|
179
|
+
### Balance lookup
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
const balance = await client.entityBalance.get({ nanoid })
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Withdrawal
|
|
186
|
+
|
|
187
|
+
Withdrawals are not available via the SDK: the withdraw endpoints require reCAPTCHA verification headers only a browser session can produce. Point users to the Rise dashboard for withdrawals.
|
|
188
|
+
|
|
189
|
+
## Webhooks
|
|
190
|
+
|
|
191
|
+
- **Default registration path**: the Rise UI / dashboard.
|
|
192
|
+
- **Programmatic management**: only use SDK webhook registration when the user
|
|
193
|
+
explicitly wants admin automation or backend-managed webhook configuration.
|
|
194
|
+
- **Receiving webhooks**: use `WebhookValidator` and `RiseWebhookEvent`.
|
|
195
|
+
|
|
196
|
+
## Output quality bar
|
|
197
|
+
|
|
198
|
+
- Generate the discovery call when the required nanoid is missing.
|
|
199
|
+
- Use the exact SDK method names that exist in `riseworks-sdk`.
|
|
200
|
+
- Prefer complete SDK flows over pseudo-code.
|