officex

ClawSkills 作者 clawskills

Complete OfficeX platform skill for end-user consumers and app developers interacting with the OfficeX REST API. Covers the full credit-based app marketplace ("Netflix meets Costco for business apps"). Use when: (1) Making HTTP calls to OfficeX cloud API, (2) Building or publishing apps on the platform, (3) Implementing billing (reserve/settle/sip/payout), (4) Managing users, installs, wallets, (5) Handling webhooks (INSTALL/UNINSTALL/RATE_LIMIT_CHANGE), (6) Embedding apps in iframes, (7) Integrating with the AI chat agent (agent_context, documentation, context_prompt), (8) Debugging API errors or auth issues. Triggers on: officex, cloud officex, credit economy, app marketplace, reserve credits, settle, sip, install app, master key, install secret, wallet, vendor inbox, payout, voucher, OTP, register user, register app, webhook, iframe, agent context, billing pattern.

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install clawskills:clawskills~mevdragon-officex
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aclawskills~mevdragon-officex/file -o mevdragon-officex.md
# OfficeX Platform

OfficeX is a membership-based app store. Users buy credits ($0.03 each: $0.02 profit + $0.01 ecosystem liability). Apps charge credits via reserve/settle. Vendors earn credits and payout to fiat (USDC on Solana or bank transfer, $0.01/credit).

**Get your credentials at:** https://officex.app/store/en/developer/

## Environments

| Env                   | API Base                                       | Chat Stream                               |
| --------------------- | ---------------------------------------------- | ----------------------------------------- |
| **Staging** (default) | `https://staging-backend.cloud.officex.app/v1` | `https://chat-staging.cloud.officex.app/` |
| **Production**        | `https://cloud.officex.app/v1`                 | `https://chat.cloud.officex.app/`         |

## Authentication

| Mode                 | Headers                                                               | Scope                                    |
| -------------------- | --------------------------------------------------------------------- | ---------------------------------------- |
| None                 | —                                                                     | Public catalog, vouchers, auth endpoints |
| Master Key           | `x-officex-user-id` + `x-officex-master-key`                          | Profile, installs, wallets, vendor apps  |
| Install Secret       | `x-officex-install-id` + `x-officex-install-secret`                   | Billing: reserve, settle, cancel, inbox  |
| Install Secret (alt) | `x-officex-user-id` + `x-officex-app-id` + `x-officex-install-secret` | Same as above (alternative lookup)       |
| Superadmin           | `x-officex-admin-secret`                                              | Full system (`/admin/*`)                 |

Install Secret is **billing only** — your app manages its own user authentication separately. The install secret handles the money, your app handles everything else.

## Credit Economy

```
User buys credits → Treasury liability increases (zero-sum: Treasury + all wallets = 0)
App reserves credits → Locked from user wallet
App sips/settles → Credits move to app wallet
Vendor payouts → Credits converted to fiat, Treasury liability decreases
```

### Decimal Credits

Credits support **decimals**. Rounding up to 1 credit ($0.03) is expensive for small operations:

| Operation   | Credits | User Pays |
| ----------- | ------- | --------- |
| Micro task  | 0.1     | $0.003    |
| Small task  | 0.25    | $0.0075   |
| Medium task | 0.5     | $0.015    |
| Standard    | 1.0     | $0.03     |

**Best practice:** Price based on actual cost. If an API call costs $0.001, charge ~0.07 credits (2x markup).

### Dual Roles

A single OfficeX account can be both **Consumer** (install and use apps) and **Vendor** (create apps and earn credits).

---

## API Endpoints

### Auth (No Auth)

```
POST /auth/register              { email }                     → { success, message }
POST /auth/login                 { email, password? }          → { success, api_key?, user_id? }
POST /auth/verify-otp            { email, code }               → { success, api_key, user_id, wallet_id? }
POST /auth/resend                { email }                     → { success, message }
POST /auth/forgot-password       { email }                     → { success, message }
POST /auth/reset-password        { email, code, new_password } → { success, message }
POST /auth/set-password          { password }            [MK]  → { success, message }
POST /auth/rotate-key            { email }                     → { success, message }
POST /auth/confirm-rotate-key    { email, code }               → { success, api_key }
POST /register-user              { email }                     → { user_id, wallet_id, api_key }  (legacy)
```

**Testing mode:** OTP hardcoded to `0000`, email sending disabled.

### User Profile [Master Key]

```
GET    /users/me                                → { user: { user_id, email, wallet_id, status } }
PATCH  /users/me                 { email? }     → { user }
POST   /users/me/rotate-key     { new_master_key } → { success }
GET    /users/me/vouchers                       → { vouchers[] }
```

### Installations [Master Key]

```
GET    /users/me/installs                       → { installs[] }
GET    /users/me/installs/{id}                  → { install (with usage stats) }
POST   /install/{app_id_or_slug} { max_per_hour?, max_per_day?, max_per_month?, allowed_until? }
                                                → { app_id, install_id, install_secret, agent_context? }  ⚠️ secret shown once
DELETE /users/me/installs/{id}                  → { success }
PATCH  /users/me/installs/{id}  { max_per_hour?, max_per_day?, max_per_month?, allowed_until?, lifetime_spend_limit? }
                                                → { install }
POST   /users/me/installs/{id}/rotate-secret    → { install_secret }
PATCH  /users/me/installs/{id}/context  { key: val | null } → { agent_context }
```

`allowed_until`: unix timestamp (-1 = never, default = now + 30d). `lifetime_spend_limit`: -1 = unlimited.

App-scoped routes (Install Secret auth):

```
PATCH  /installs/{install_id}/context  { key: val | null } → { agent_context }
POST   /installs/{install_id}/inbox    { id, title, text, url?, icon? } → { message_id }
```

### Vendor Apps [Master Key]

```
GET    /users/me/apps                           → { apps[] }
POST   /register-app             (see full schema below)
                                                → { app_id, destination_wallet_id }
GET    /users/me/apps/{app_id}                  → { app }
PATCH  /users/me/apps/{app_id}   (see full schema below)
                                                → { app }
DELETE /users/me/apps/{app_id}                  → { success }
GET    /users/me/apps/{app_id}/inbox            → { reservations[], pagination? }
POST   /users/me/apps/{app_id}/inbox/{log_id}/ack → { success }
GET    /users/me/apps/{app_id}/installs         → { installs[] }
```

### Public Catalog (No Auth)

```
GET    /apps                                    → { apps[], pagination? }
GET    /apps/{app_id}                           → { app }
```

### Credits & Balance [Master Key]

```
POST   /purchase-credits         { amount, payment_method: { type, token }, idempotency_key? }
                                                → { credits_added, new_balance, transaction_id }
GET    /balance                                 → { wallet_id, available, reserved, total }
```

### Reserve & Settle [Install Secret]

```
POST   /reserve                  { amount, job_id, metadata? }
                                                → { reservation_id, amount_reserved }
POST   /settle                   { reservation_id, amount, final? }
                                                → { settled_amount, remaining_reserved, status }
GET    /reservations/{id}                       → { reservation }
POST   /reservations/{id}/cancel                → { refunded_amount, status }
POST   /reservations/{id}/settle { amount, final? } → { settled_amount, status }
```

`final: true` = complete + refund remainder. `final: false` (default) = sip (partial).

Reserve errors: `INSTALL_EXPIRED`, `RATE_LIMITED`, `INSUFFICIENT_FUNDS`, `DUPLICATE_JOB`, `LIFETIME_LIMIT_REACHED`

### Wallets [Master Key]

```
GET    /wallets/{id}                            → { wallet_id, available, reserved, total, owner_type }
GET    /wallets/{id}/transactions  ?limit=&cursor= → { transactions[], pagination? }
GET    /wallets/{id}/transactions/{log_id}      → { transaction }
GET    /wallets/{id}/reservations  ?direction=   → { reservations[] }
GET    /wallets/{id}/reservations/{resv_id}     → { reservation }
GET    /wallets/{id}/payouts                    → { payouts[] }
GET    /wallets/{id}/payouts/{payout_id}        → { payout }
```

### Payouts [Master Key]

```
POST   /payout                   { wallet_id, amount, destination: { type, ac