@1claw/openapi-spec 0.61.47 → 0.61.49
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/openapi.json +492 -2
- package/openapi.yaml +364 -2
- package/package.json +2 -2
package/openapi.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "1Claw API",
|
|
5
|
-
"version": "0.61.
|
|
5
|
+
"version": "0.61.49",
|
|
6
6
|
"description": "Secure secret management for AI agents. Provides vaults, secrets,\npolicy-based access control, agent identity, Intents API,\nsharing, billing, and audit logging. Automations (workflow_spec,\nwebhook tokens, event triggers, Assist), cloud runtimes with\ninteractive shell sessions, agent memory, and discovery.\n\n## Domains\n\n`api.1claw.co` is canonical: it is the OIDC issuer, the `aud` the API\nmints, and the first entry in `servers` — a generated client takes its\nbase URL from there, and the previous ordering pointed every SDK at the\ndomain the issuer had already left. `api.1claw.xyz` still answers and is\nstill accepted on token validation, because tokens minted before the\nmove carry it; it is never minted now.\n\nOne deliberate exception: the Shroud attestation identity token is\nrequested from GCP with `audience: https://api.1claw.xyz`, so\n`/v1/shroud/attestation` reports that as its `expected_audience`. That\nis accurate rather than stale — the audience is a verification contract\nwith anyone already checking the token, and moving it is a breaking\nchange for them, not a rename.\n\nAll endpoints require JWT Bearer authentication unless marked with\n`security: []`.\n",
|
|
7
7
|
"contact": {
|
|
8
8
|
"email": "ops@1claw.co"
|
|
@@ -7760,6 +7760,194 @@
|
|
|
7760
7760
|
}
|
|
7761
7761
|
}
|
|
7762
7762
|
},
|
|
7763
|
+
"/v1/staking/points": {
|
|
7764
|
+
"get": {
|
|
7765
|
+
"tags": [
|
|
7766
|
+
"Billing"
|
|
7767
|
+
],
|
|
7768
|
+
"summary": "Staking points for the signed-in user's wallet",
|
|
7769
|
+
"description": "Points earned by staking, what has been redeemed here, and what is\nleft.\n\nThe two halves come from different places on purpose. `earned` is\nread per request from the staking service, which recomputes it from\non-chain events; `spent` is this service's own append-only ledger.\n`available` is the difference, floored at zero.\n\nThe wallet is the one on the account, proven by a SIWE signature at\nsign-in — there is no way to ask about another address.\n\n`can_redeem` is false until the account has a real, verified email:\na wallet signature proves possession of a key, not a reachable\nperson, and `redeem_blocked_reason` says what to do about it.\n",
|
|
7770
|
+
"operationId": "getStakingPoints",
|
|
7771
|
+
"responses": {
|
|
7772
|
+
"200": {
|
|
7773
|
+
"description": "Points and rates",
|
|
7774
|
+
"content": {
|
|
7775
|
+
"application/json": {
|
|
7776
|
+
"schema": {
|
|
7777
|
+
"type": "object",
|
|
7778
|
+
"properties": {
|
|
7779
|
+
"wallet_address": {
|
|
7780
|
+
"type": "string"
|
|
7781
|
+
},
|
|
7782
|
+
"earned": {
|
|
7783
|
+
"type": "integer",
|
|
7784
|
+
"format": "int64"
|
|
7785
|
+
},
|
|
7786
|
+
"spent": {
|
|
7787
|
+
"type": "integer",
|
|
7788
|
+
"format": "int64"
|
|
7789
|
+
},
|
|
7790
|
+
"available": {
|
|
7791
|
+
"type": "integer",
|
|
7792
|
+
"format": "int64"
|
|
7793
|
+
},
|
|
7794
|
+
"can_redeem": {
|
|
7795
|
+
"type": "boolean"
|
|
7796
|
+
},
|
|
7797
|
+
"redeem_blocked_reason": {
|
|
7798
|
+
"type": "string",
|
|
7799
|
+
"nullable": true
|
|
7800
|
+
},
|
|
7801
|
+
"rates": {
|
|
7802
|
+
"type": "object",
|
|
7803
|
+
"properties": {
|
|
7804
|
+
"points_per_pro_month": {
|
|
7805
|
+
"type": "integer"
|
|
7806
|
+
},
|
|
7807
|
+
"micro_usd_per_point": {
|
|
7808
|
+
"type": "integer"
|
|
7809
|
+
},
|
|
7810
|
+
"points_per_day_per_100m_tokens": {
|
|
7811
|
+
"type": "integer"
|
|
7812
|
+
},
|
|
7813
|
+
"max_pro_months_per_redemption": {
|
|
7814
|
+
"type": "integer"
|
|
7815
|
+
}
|
|
7816
|
+
}
|
|
7817
|
+
},
|
|
7818
|
+
"recent": {
|
|
7819
|
+
"type": "array",
|
|
7820
|
+
"items": {
|
|
7821
|
+
"type": "object",
|
|
7822
|
+
"properties": {
|
|
7823
|
+
"id": {
|
|
7824
|
+
"type": "string",
|
|
7825
|
+
"format": "uuid"
|
|
7826
|
+
},
|
|
7827
|
+
"wallet_address": {
|
|
7828
|
+
"type": "string"
|
|
7829
|
+
},
|
|
7830
|
+
"points_spent": {
|
|
7831
|
+
"type": "integer",
|
|
7832
|
+
"format": "int64"
|
|
7833
|
+
},
|
|
7834
|
+
"reward_type": {
|
|
7835
|
+
"type": "string",
|
|
7836
|
+
"enum": [
|
|
7837
|
+
"pro_months",
|
|
7838
|
+
"credits"
|
|
7839
|
+
]
|
|
7840
|
+
},
|
|
7841
|
+
"reward_detail": {
|
|
7842
|
+
"type": "object"
|
|
7843
|
+
},
|
|
7844
|
+
"created_at": {
|
|
7845
|
+
"type": "string",
|
|
7846
|
+
"format": "date-time"
|
|
7847
|
+
}
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7852
|
+
}
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
},
|
|
7856
|
+
"400": {
|
|
7857
|
+
"description": "No wallet linked to this account"
|
|
7858
|
+
},
|
|
7859
|
+
"403": {
|
|
7860
|
+
"description": "Only a signed-in person can read staking points"
|
|
7861
|
+
},
|
|
7862
|
+
"503": {
|
|
7863
|
+
"description": "The staking service could not report points. Deliberately not\nreported as zero — that would tell a staker their earnings\nhad vanished.\n"
|
|
7864
|
+
}
|
|
7865
|
+
}
|
|
7866
|
+
}
|
|
7867
|
+
},
|
|
7868
|
+
"/v1/staking/redeem": {
|
|
7869
|
+
"post": {
|
|
7870
|
+
"tags": [
|
|
7871
|
+
"Billing"
|
|
7872
|
+
],
|
|
7873
|
+
"summary": "Redeem staking points for plan time or credits",
|
|
7874
|
+
"description": "Spends points from the wallet on the account.\n\n`quantity` is **months** for `pro_months` and **points** for\n`credits`; the response always states the cost actually charged.\n\nPro months extend an existing period rather than replacing it, so\nredeeming twice does not discard the time already granted. They are\nrefused when the organisation has a Stripe subscription, or is on a\ntier above Pro: a comped tier would overwrite the plan being paid\nfor and would never expire. Credits apply on top of a subscription\nand are the right choice there.\n\nRedemption serialises on the wallet's ledger, so two concurrent\nrequests cannot spend the same points.\n",
|
|
7875
|
+
"operationId": "redeemStakingPoints",
|
|
7876
|
+
"requestBody": {
|
|
7877
|
+
"required": true,
|
|
7878
|
+
"content": {
|
|
7879
|
+
"application/json": {
|
|
7880
|
+
"schema": {
|
|
7881
|
+
"type": "object",
|
|
7882
|
+
"required": [
|
|
7883
|
+
"reward_type",
|
|
7884
|
+
"quantity"
|
|
7885
|
+
],
|
|
7886
|
+
"properties": {
|
|
7887
|
+
"reward_type": {
|
|
7888
|
+
"type": "string",
|
|
7889
|
+
"enum": [
|
|
7890
|
+
"pro_months",
|
|
7891
|
+
"credits"
|
|
7892
|
+
]
|
|
7893
|
+
},
|
|
7894
|
+
"quantity": {
|
|
7895
|
+
"type": "integer",
|
|
7896
|
+
"format": "int64",
|
|
7897
|
+
"minimum": 1,
|
|
7898
|
+
"description": "Months for pro_months; points for credits"
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
}
|
|
7902
|
+
}
|
|
7903
|
+
}
|
|
7904
|
+
},
|
|
7905
|
+
"responses": {
|
|
7906
|
+
"200": {
|
|
7907
|
+
"description": "Redeemed",
|
|
7908
|
+
"content": {
|
|
7909
|
+
"application/json": {
|
|
7910
|
+
"schema": {
|
|
7911
|
+
"type": "object",
|
|
7912
|
+
"properties": {
|
|
7913
|
+
"redemption_id": {
|
|
7914
|
+
"type": "string",
|
|
7915
|
+
"format": "uuid"
|
|
7916
|
+
},
|
|
7917
|
+
"points_spent": {
|
|
7918
|
+
"type": "integer",
|
|
7919
|
+
"format": "int64"
|
|
7920
|
+
},
|
|
7921
|
+
"remaining_available": {
|
|
7922
|
+
"type": "integer",
|
|
7923
|
+
"format": "int64"
|
|
7924
|
+
},
|
|
7925
|
+
"reward_type": {
|
|
7926
|
+
"type": "string"
|
|
7927
|
+
},
|
|
7928
|
+
"reward_detail": {
|
|
7929
|
+
"type": "object"
|
|
7930
|
+
}
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
}
|
|
7934
|
+
}
|
|
7935
|
+
},
|
|
7936
|
+
"400": {
|
|
7937
|
+
"description": "Not enough points, or no wallet linked"
|
|
7938
|
+
},
|
|
7939
|
+
"403": {
|
|
7940
|
+
"description": "A real verified email is required before redeeming"
|
|
7941
|
+
},
|
|
7942
|
+
"409": {
|
|
7943
|
+
"description": "Pro months refused because the organisation's billing is owned\nby Stripe, or its tier is above Pro. Redeem credits instead.\n"
|
|
7944
|
+
},
|
|
7945
|
+
"503": {
|
|
7946
|
+
"description": "The staking service could not report points; nothing was charged"
|
|
7947
|
+
}
|
|
7948
|
+
}
|
|
7949
|
+
}
|
|
7950
|
+
},
|
|
7763
7951
|
"/v1/billing/credits/topup": {
|
|
7764
7952
|
"post": {
|
|
7765
7953
|
"tags": [
|
|
@@ -11372,6 +11560,146 @@
|
|
|
11372
11560
|
}
|
|
11373
11561
|
}
|
|
11374
11562
|
},
|
|
11563
|
+
"/v1/treasury/wallets/{chain}/sign-message": {
|
|
11564
|
+
"post": {
|
|
11565
|
+
"tags": [
|
|
11566
|
+
"Treasury"
|
|
11567
|
+
],
|
|
11568
|
+
"summary": "Sign a message with a human wallet (EIP-191)",
|
|
11569
|
+
"description": "`personal_sign` over the given text, hashed as `\\x19Ethereum Signed Message:\\n<len>` + message — what viem's `verifyMessage` and ethers' `verifyMessage` expect.\n\nHuman callers only; an agent signs with its own key via `POST /v1/agents/{agent_id}/sign`. Gated exactly as a send is: `X-Auth-Confirm` step-up scored as a Send action, wallet access policies (`WalletAction::Sign`), and a refusal for wallets whose key is split or passkey-owned — those have no server-side key and will not fall back to one.\n\nEVM chains only.\n",
|
|
11570
|
+
"operationId": "signTreasuryMessage",
|
|
11571
|
+
"parameters": [
|
|
11572
|
+
{
|
|
11573
|
+
"name": "chain",
|
|
11574
|
+
"in": "path",
|
|
11575
|
+
"required": true,
|
|
11576
|
+
"schema": {
|
|
11577
|
+
"type": "string",
|
|
11578
|
+
"example": "ethereum"
|
|
11579
|
+
}
|
|
11580
|
+
},
|
|
11581
|
+
{
|
|
11582
|
+
"name": "X-Auth-Confirm",
|
|
11583
|
+
"in": "header",
|
|
11584
|
+
"required": true,
|
|
11585
|
+
"schema": {
|
|
11586
|
+
"type": "string"
|
|
11587
|
+
},
|
|
11588
|
+
"description": "Account password, or a `rat_` token from `POST /v1/auth/reauth/complete`."
|
|
11589
|
+
}
|
|
11590
|
+
],
|
|
11591
|
+
"requestBody": {
|
|
11592
|
+
"required": true,
|
|
11593
|
+
"content": {
|
|
11594
|
+
"application/json": {
|
|
11595
|
+
"schema": {
|
|
11596
|
+
"type": "object",
|
|
11597
|
+
"required": [
|
|
11598
|
+
"message"
|
|
11599
|
+
],
|
|
11600
|
+
"properties": {
|
|
11601
|
+
"message": {
|
|
11602
|
+
"type": "string",
|
|
11603
|
+
"maxLength": 16384,
|
|
11604
|
+
"example": "Sign in to Example at 2026-10-01T10:00:00Z"
|
|
11605
|
+
}
|
|
11606
|
+
}
|
|
11607
|
+
}
|
|
11608
|
+
}
|
|
11609
|
+
}
|
|
11610
|
+
},
|
|
11611
|
+
"responses": {
|
|
11612
|
+
"200": {
|
|
11613
|
+
"description": "Signature",
|
|
11614
|
+
"content": {
|
|
11615
|
+
"application/json": {
|
|
11616
|
+
"schema": {
|
|
11617
|
+
"$ref": "#/components/schemas/WalletSignature"
|
|
11618
|
+
}
|
|
11619
|
+
}
|
|
11620
|
+
}
|
|
11621
|
+
},
|
|
11622
|
+
"400": {
|
|
11623
|
+
"description": "Empty or oversized message, or a non-EVM chain"
|
|
11624
|
+
},
|
|
11625
|
+
"403": {
|
|
11626
|
+
"description": "Agent caller, missing or insufficient step-up, denied by a wallet access policy, or a self-custody wallet the server cannot sign for.\n"
|
|
11627
|
+
},
|
|
11628
|
+
"404": {
|
|
11629
|
+
"description": "No wallet on that chain for this user"
|
|
11630
|
+
}
|
|
11631
|
+
}
|
|
11632
|
+
}
|
|
11633
|
+
},
|
|
11634
|
+
"/v1/treasury/wallets/{chain}/sign-typed-data": {
|
|
11635
|
+
"post": {
|
|
11636
|
+
"tags": [
|
|
11637
|
+
"Treasury"
|
|
11638
|
+
],
|
|
11639
|
+
"summary": "Sign EIP-712 typed data with a human wallet",
|
|
11640
|
+
"description": "Hashes and signs a full EIP-712 payload. Include `EIP712Domain` in `types` — viem and ethers synthesise that entry and omit it, and this hashes exactly what you send.\n\nSame gates as `sign-message`.\n",
|
|
11641
|
+
"operationId": "signTreasuryTypedData",
|
|
11642
|
+
"parameters": [
|
|
11643
|
+
{
|
|
11644
|
+
"name": "chain",
|
|
11645
|
+
"in": "path",
|
|
11646
|
+
"required": true,
|
|
11647
|
+
"schema": {
|
|
11648
|
+
"type": "string",
|
|
11649
|
+
"example": "base"
|
|
11650
|
+
}
|
|
11651
|
+
},
|
|
11652
|
+
{
|
|
11653
|
+
"name": "X-Auth-Confirm",
|
|
11654
|
+
"in": "header",
|
|
11655
|
+
"required": true,
|
|
11656
|
+
"schema": {
|
|
11657
|
+
"type": "string"
|
|
11658
|
+
}
|
|
11659
|
+
}
|
|
11660
|
+
],
|
|
11661
|
+
"requestBody": {
|
|
11662
|
+
"required": true,
|
|
11663
|
+
"content": {
|
|
11664
|
+
"application/json": {
|
|
11665
|
+
"schema": {
|
|
11666
|
+
"type": "object",
|
|
11667
|
+
"required": [
|
|
11668
|
+
"typed_data"
|
|
11669
|
+
],
|
|
11670
|
+
"properties": {
|
|
11671
|
+
"typed_data": {
|
|
11672
|
+
"type": "object",
|
|
11673
|
+
"description": "`types`, `primaryType`, `domain`, `message`."
|
|
11674
|
+
}
|
|
11675
|
+
}
|
|
11676
|
+
}
|
|
11677
|
+
}
|
|
11678
|
+
}
|
|
11679
|
+
},
|
|
11680
|
+
"responses": {
|
|
11681
|
+
"200": {
|
|
11682
|
+
"description": "Signature",
|
|
11683
|
+
"content": {
|
|
11684
|
+
"application/json": {
|
|
11685
|
+
"schema": {
|
|
11686
|
+
"$ref": "#/components/schemas/WalletSignature"
|
|
11687
|
+
}
|
|
11688
|
+
}
|
|
11689
|
+
}
|
|
11690
|
+
},
|
|
11691
|
+
"400": {
|
|
11692
|
+
"description": "Malformed EIP-712 payload, or a non-EVM chain"
|
|
11693
|
+
},
|
|
11694
|
+
"403": {
|
|
11695
|
+
"description": "Same refusals as sign-message"
|
|
11696
|
+
},
|
|
11697
|
+
"404": {
|
|
11698
|
+
"description": "No wallet on that chain for this user"
|
|
11699
|
+
}
|
|
11700
|
+
}
|
|
11701
|
+
}
|
|
11702
|
+
},
|
|
11375
11703
|
"/v1/treasury/wallets/{chain}/swap": {
|
|
11376
11704
|
"post": {
|
|
11377
11705
|
"tags": [
|
|
@@ -17534,6 +17862,143 @@
|
|
|
17534
17862
|
}
|
|
17535
17863
|
}
|
|
17536
17864
|
},
|
|
17865
|
+
"/v1/auth/siwe/challenge": {
|
|
17866
|
+
"post": {
|
|
17867
|
+
"tags": [
|
|
17868
|
+
"Authentication"
|
|
17869
|
+
],
|
|
17870
|
+
"summary": "Start wallet sign-in (SIWE)",
|
|
17871
|
+
"description": "Returns the exact EIP-4361 message to sign, for signing in to the\ndashboard with an Ethereum wallet.\n\nThe message is built server-side and returned whole: the domain and\nthe nonce are ours to decide, and a client that assembles its own\nmessage is a client that can be talked into signing a different\none. Sign it unmodified and post it back to\n`/v1/auth/siwe/verify`.\n\nThe nonce is single-use and valid for five minutes. Distinct from\n`/v1/platform/siwe/challenge`, which needs a `plt_` caller and\nissues nonces scoped to one platform app for *its* end users.\n",
|
|
17872
|
+
"operationId": "siweLoginChallenge",
|
|
17873
|
+
"security": [],
|
|
17874
|
+
"requestBody": {
|
|
17875
|
+
"required": true,
|
|
17876
|
+
"content": {
|
|
17877
|
+
"application/json": {
|
|
17878
|
+
"schema": {
|
|
17879
|
+
"type": "object",
|
|
17880
|
+
"required": [
|
|
17881
|
+
"address"
|
|
17882
|
+
],
|
|
17883
|
+
"properties": {
|
|
17884
|
+
"address": {
|
|
17885
|
+
"type": "string",
|
|
17886
|
+
"description": "0x-prefixed 20-byte Ethereum address",
|
|
17887
|
+
"example": "0x0000000000000000000000000000000000000001"
|
|
17888
|
+
}
|
|
17889
|
+
}
|
|
17890
|
+
}
|
|
17891
|
+
}
|
|
17892
|
+
}
|
|
17893
|
+
},
|
|
17894
|
+
"responses": {
|
|
17895
|
+
"200": {
|
|
17896
|
+
"description": "Message to sign",
|
|
17897
|
+
"content": {
|
|
17898
|
+
"application/json": {
|
|
17899
|
+
"schema": {
|
|
17900
|
+
"type": "object",
|
|
17901
|
+
"properties": {
|
|
17902
|
+
"message": {
|
|
17903
|
+
"type": "string",
|
|
17904
|
+
"description": "Sign this verbatim"
|
|
17905
|
+
},
|
|
17906
|
+
"nonce": {
|
|
17907
|
+
"type": "string"
|
|
17908
|
+
},
|
|
17909
|
+
"expires_in_secs": {
|
|
17910
|
+
"type": "integer"
|
|
17911
|
+
}
|
|
17912
|
+
}
|
|
17913
|
+
}
|
|
17914
|
+
}
|
|
17915
|
+
}
|
|
17916
|
+
},
|
|
17917
|
+
"400": {
|
|
17918
|
+
"description": "Not a valid Ethereum address"
|
|
17919
|
+
},
|
|
17920
|
+
"429": {
|
|
17921
|
+
"description": "Rate limited"
|
|
17922
|
+
}
|
|
17923
|
+
}
|
|
17924
|
+
}
|
|
17925
|
+
},
|
|
17926
|
+
"/v1/auth/siwe/verify": {
|
|
17927
|
+
"post": {
|
|
17928
|
+
"tags": [
|
|
17929
|
+
"Authentication"
|
|
17930
|
+
],
|
|
17931
|
+
"summary": "Complete wallet sign-in and get a JWT",
|
|
17932
|
+
"description": "Verifies the signature over the challenge message and returns an\nordinary user JWT — the same token social login and email-OTP\nproduce.\n\nFirst sign-in for an address creates a user and org. That user's\nemail starts synthetic (`email_pending: true`) and unverified: a\nwallet signature proves possession of a key, not a reachable\nperson. Staking redemption refuses until a real address is added\nand confirmed.\n\nThe wallet recovered from the signature is stored on the account\nand is the identity staking points are counted against. It is\nnever accepted from a request body anywhere.\n",
|
|
17933
|
+
"operationId": "siweLoginVerify",
|
|
17934
|
+
"security": [],
|
|
17935
|
+
"requestBody": {
|
|
17936
|
+
"required": true,
|
|
17937
|
+
"content": {
|
|
17938
|
+
"application/json": {
|
|
17939
|
+
"schema": {
|
|
17940
|
+
"type": "object",
|
|
17941
|
+
"required": [
|
|
17942
|
+
"message",
|
|
17943
|
+
"signature"
|
|
17944
|
+
],
|
|
17945
|
+
"properties": {
|
|
17946
|
+
"message": {
|
|
17947
|
+
"type": "string",
|
|
17948
|
+
"description": "The challenge message, unmodified"
|
|
17949
|
+
},
|
|
17950
|
+
"signature": {
|
|
17951
|
+
"type": "string",
|
|
17952
|
+
"description": "Hex signature over the message"
|
|
17953
|
+
}
|
|
17954
|
+
}
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17957
|
+
}
|
|
17958
|
+
},
|
|
17959
|
+
"responses": {
|
|
17960
|
+
"200": {
|
|
17961
|
+
"description": "Authenticated",
|
|
17962
|
+
"content": {
|
|
17963
|
+
"application/json": {
|
|
17964
|
+
"schema": {
|
|
17965
|
+
"type": "object",
|
|
17966
|
+
"properties": {
|
|
17967
|
+
"token": {
|
|
17968
|
+
"type": "string"
|
|
17969
|
+
},
|
|
17970
|
+
"user_id": {
|
|
17971
|
+
"type": "string",
|
|
17972
|
+
"format": "uuid"
|
|
17973
|
+
},
|
|
17974
|
+
"org_id": {
|
|
17975
|
+
"type": "string",
|
|
17976
|
+
"format": "uuid"
|
|
17977
|
+
},
|
|
17978
|
+
"wallet_address": {
|
|
17979
|
+
"type": "string"
|
|
17980
|
+
},
|
|
17981
|
+
"is_new_user": {
|
|
17982
|
+
"type": "boolean"
|
|
17983
|
+
},
|
|
17984
|
+
"email_pending": {
|
|
17985
|
+
"type": "boolean",
|
|
17986
|
+
"description": "True while the account email is still the synthetic\nwallet address. Redemption is blocked until a real\none is verified.\n"
|
|
17987
|
+
}
|
|
17988
|
+
}
|
|
17989
|
+
}
|
|
17990
|
+
}
|
|
17991
|
+
}
|
|
17992
|
+
},
|
|
17993
|
+
"400": {
|
|
17994
|
+
"description": "Expired or reused challenge, or a message signed for another domain"
|
|
17995
|
+
},
|
|
17996
|
+
"401": {
|
|
17997
|
+
"description": "Signature does not match the address in the message"
|
|
17998
|
+
}
|
|
17999
|
+
}
|
|
18000
|
+
}
|
|
18001
|
+
},
|
|
17537
18002
|
"/v1/oauth/authorize": {
|
|
17538
18003
|
"get": {
|
|
17539
18004
|
"tags": [
|
|
@@ -28565,6 +29030,10 @@
|
|
|
28565
29030
|
"granted_read": {
|
|
28566
29031
|
"type": "boolean",
|
|
28567
29032
|
"description": "False when the secret was stored but the read grant could not be written — the agent will need access granted by hand.\n"
|
|
29033
|
+
},
|
|
29034
|
+
"bound_new_vault": {
|
|
29035
|
+
"type": "boolean",
|
|
29036
|
+
"description": "True when the agent had to be bound to a vault it was not bound to before. Its access is correct from now on, but a JWT carries the `vault_ids` it was minted with, so a token the agent already holds is refused until it re-mints. Answering into a vault the agent already reaches avoids this.\n"
|
|
28568
29037
|
}
|
|
28569
29038
|
}
|
|
28570
29039
|
}
|
|
@@ -28572,7 +29041,7 @@
|
|
|
28572
29041
|
}
|
|
28573
29042
|
},
|
|
28574
29043
|
"400": {
|
|
28575
|
-
"description": "Already answered, expired,
|
|
29044
|
+
"description": "Already answered, expired, an invalid path, or nothing is stored at that path — the location the agent is sent to has to be real.\n"
|
|
28576
29045
|
},
|
|
28577
29046
|
"403": {
|
|
28578
29047
|
"description": "Called by an agent"
|
|
@@ -42408,6 +42877,27 @@
|
|
|
42408
42877
|
}
|
|
42409
42878
|
}
|
|
42410
42879
|
},
|
|
42880
|
+
"WalletSignature": {
|
|
42881
|
+
"type": "object",
|
|
42882
|
+
"required": [
|
|
42883
|
+
"signature",
|
|
42884
|
+
"address",
|
|
42885
|
+
"chain"
|
|
42886
|
+
],
|
|
42887
|
+
"properties": {
|
|
42888
|
+
"signature": {
|
|
42889
|
+
"type": "string",
|
|
42890
|
+
"description": "65-byte `0x`-prefixed signature, r‖s‖v."
|
|
42891
|
+
},
|
|
42892
|
+
"address": {
|
|
42893
|
+
"type": "string",
|
|
42894
|
+
"description": "The signing wallet, so it can be passed straight to `verifyMessage`."
|
|
42895
|
+
},
|
|
42896
|
+
"chain": {
|
|
42897
|
+
"type": "string"
|
|
42898
|
+
}
|
|
42899
|
+
}
|
|
42900
|
+
},
|
|
42411
42901
|
"SecretRequest": {
|
|
42412
42902
|
"type": "object",
|
|
42413
42903
|
"description": "An agent's open ask, as the human sees it. Carries the request and, once fulfilled, a reference — never a value.\n",
|
package/openapi.yaml
CHANGED
|
@@ -2,7 +2,7 @@ openapi: 3.1.0
|
|
|
2
2
|
|
|
3
3
|
info:
|
|
4
4
|
title: 1Claw API
|
|
5
|
-
version: "0.61.
|
|
5
|
+
version: "0.61.49"
|
|
6
6
|
description: |
|
|
7
7
|
Secure secret management for AI agents. Provides vaults, secrets,
|
|
8
8
|
policy-based access control, agent identity, Intents API,
|
|
@@ -5015,6 +5015,132 @@ paths:
|
|
|
5015
5015
|
schema:
|
|
5016
5016
|
$ref: "#/components/schemas/SubscriptionResponse"
|
|
5017
5017
|
|
|
5018
|
+
/v1/staking/points:
|
|
5019
|
+
get:
|
|
5020
|
+
tags: [Billing]
|
|
5021
|
+
summary: Staking points for the signed-in user's wallet
|
|
5022
|
+
description: |
|
|
5023
|
+
Points earned by staking, what has been redeemed here, and what is
|
|
5024
|
+
left.
|
|
5025
|
+
|
|
5026
|
+
The two halves come from different places on purpose. `earned` is
|
|
5027
|
+
read per request from the staking service, which recomputes it from
|
|
5028
|
+
on-chain events; `spent` is this service's own append-only ledger.
|
|
5029
|
+
`available` is the difference, floored at zero.
|
|
5030
|
+
|
|
5031
|
+
The wallet is the one on the account, proven by a SIWE signature at
|
|
5032
|
+
sign-in — there is no way to ask about another address.
|
|
5033
|
+
|
|
5034
|
+
`can_redeem` is false until the account has a real, verified email:
|
|
5035
|
+
a wallet signature proves possession of a key, not a reachable
|
|
5036
|
+
person, and `redeem_blocked_reason` says what to do about it.
|
|
5037
|
+
operationId: getStakingPoints
|
|
5038
|
+
responses:
|
|
5039
|
+
"200":
|
|
5040
|
+
description: Points and rates
|
|
5041
|
+
content:
|
|
5042
|
+
application/json:
|
|
5043
|
+
schema:
|
|
5044
|
+
type: object
|
|
5045
|
+
properties:
|
|
5046
|
+
wallet_address: { type: string }
|
|
5047
|
+
earned: { type: integer, format: int64 }
|
|
5048
|
+
spent: { type: integer, format: int64 }
|
|
5049
|
+
available: { type: integer, format: int64 }
|
|
5050
|
+
can_redeem: { type: boolean }
|
|
5051
|
+
redeem_blocked_reason:
|
|
5052
|
+
type: string
|
|
5053
|
+
nullable: true
|
|
5054
|
+
rates:
|
|
5055
|
+
type: object
|
|
5056
|
+
properties:
|
|
5057
|
+
points_per_pro_month: { type: integer }
|
|
5058
|
+
micro_usd_per_point: { type: integer }
|
|
5059
|
+
points_per_day_per_100m_tokens: { type: integer }
|
|
5060
|
+
max_pro_months_per_redemption: { type: integer }
|
|
5061
|
+
recent:
|
|
5062
|
+
type: array
|
|
5063
|
+
items:
|
|
5064
|
+
type: object
|
|
5065
|
+
properties:
|
|
5066
|
+
id: { type: string, format: uuid }
|
|
5067
|
+
wallet_address: { type: string }
|
|
5068
|
+
points_spent: { type: integer, format: int64 }
|
|
5069
|
+
reward_type:
|
|
5070
|
+
type: string
|
|
5071
|
+
enum: [pro_months, credits]
|
|
5072
|
+
reward_detail: { type: object }
|
|
5073
|
+
created_at: { type: string, format: date-time }
|
|
5074
|
+
"400":
|
|
5075
|
+
description: No wallet linked to this account
|
|
5076
|
+
"403":
|
|
5077
|
+
description: Only a signed-in person can read staking points
|
|
5078
|
+
"503":
|
|
5079
|
+
description: |
|
|
5080
|
+
The staking service could not report points. Deliberately not
|
|
5081
|
+
reported as zero — that would tell a staker their earnings
|
|
5082
|
+
had vanished.
|
|
5083
|
+
|
|
5084
|
+
/v1/staking/redeem:
|
|
5085
|
+
post:
|
|
5086
|
+
tags: [Billing]
|
|
5087
|
+
summary: Redeem staking points for plan time or credits
|
|
5088
|
+
description: |
|
|
5089
|
+
Spends points from the wallet on the account.
|
|
5090
|
+
|
|
5091
|
+
`quantity` is **months** for `pro_months` and **points** for
|
|
5092
|
+
`credits`; the response always states the cost actually charged.
|
|
5093
|
+
|
|
5094
|
+
Pro months extend an existing period rather than replacing it, so
|
|
5095
|
+
redeeming twice does not discard the time already granted. They are
|
|
5096
|
+
refused when the organisation has a Stripe subscription, or is on a
|
|
5097
|
+
tier above Pro: a comped tier would overwrite the plan being paid
|
|
5098
|
+
for and would never expire. Credits apply on top of a subscription
|
|
5099
|
+
and are the right choice there.
|
|
5100
|
+
|
|
5101
|
+
Redemption serialises on the wallet's ledger, so two concurrent
|
|
5102
|
+
requests cannot spend the same points.
|
|
5103
|
+
operationId: redeemStakingPoints
|
|
5104
|
+
requestBody:
|
|
5105
|
+
required: true
|
|
5106
|
+
content:
|
|
5107
|
+
application/json:
|
|
5108
|
+
schema:
|
|
5109
|
+
type: object
|
|
5110
|
+
required: [reward_type, quantity]
|
|
5111
|
+
properties:
|
|
5112
|
+
reward_type:
|
|
5113
|
+
type: string
|
|
5114
|
+
enum: [pro_months, credits]
|
|
5115
|
+
quantity:
|
|
5116
|
+
type: integer
|
|
5117
|
+
format: int64
|
|
5118
|
+
minimum: 1
|
|
5119
|
+
description: Months for pro_months; points for credits
|
|
5120
|
+
responses:
|
|
5121
|
+
"200":
|
|
5122
|
+
description: Redeemed
|
|
5123
|
+
content:
|
|
5124
|
+
application/json:
|
|
5125
|
+
schema:
|
|
5126
|
+
type: object
|
|
5127
|
+
properties:
|
|
5128
|
+
redemption_id: { type: string, format: uuid }
|
|
5129
|
+
points_spent: { type: integer, format: int64 }
|
|
5130
|
+
remaining_available: { type: integer, format: int64 }
|
|
5131
|
+
reward_type: { type: string }
|
|
5132
|
+
reward_detail: { type: object }
|
|
5133
|
+
"400":
|
|
5134
|
+
description: Not enough points, or no wallet linked
|
|
5135
|
+
"403":
|
|
5136
|
+
description: A real verified email is required before redeeming
|
|
5137
|
+
"409":
|
|
5138
|
+
description: |
|
|
5139
|
+
Pro months refused because the organisation's billing is owned
|
|
5140
|
+
by Stripe, or its tier is above Pro. Redeem credits instead.
|
|
5141
|
+
"503":
|
|
5142
|
+
description: The staking service could not report points; nothing was charged
|
|
5143
|
+
|
|
5018
5144
|
/v1/billing/credits/topup:
|
|
5019
5145
|
post:
|
|
5020
5146
|
tags: [Billing]
|
|
@@ -7207,6 +7333,109 @@ paths:
|
|
|
7207
7333
|
"404":
|
|
7208
7334
|
$ref: "#/components/responses/NotFound"
|
|
7209
7335
|
|
|
7336
|
+
/v1/treasury/wallets/{chain}/sign-message:
|
|
7337
|
+
post:
|
|
7338
|
+
tags: [Treasury]
|
|
7339
|
+
summary: "Sign a message with a human wallet (EIP-191)"
|
|
7340
|
+
description: >
|
|
7341
|
+
`personal_sign` over the given text, hashed as
|
|
7342
|
+
`\x19Ethereum Signed Message:\n<len>` + message — what
|
|
7343
|
+
viem's `verifyMessage` and ethers' `verifyMessage` expect.
|
|
7344
|
+
|
|
7345
|
+
|
|
7346
|
+
Human callers only; an agent signs with its own key via
|
|
7347
|
+
`POST /v1/agents/{agent_id}/sign`. Gated exactly as a send
|
|
7348
|
+
is: `X-Auth-Confirm` step-up scored as a Send action, wallet
|
|
7349
|
+
access policies (`WalletAction::Sign`), and a refusal for
|
|
7350
|
+
wallets whose key is split or passkey-owned — those have no
|
|
7351
|
+
server-side key and will not fall back to one.
|
|
7352
|
+
|
|
7353
|
+
|
|
7354
|
+
EVM chains only.
|
|
7355
|
+
operationId: signTreasuryMessage
|
|
7356
|
+
parameters:
|
|
7357
|
+
- name: chain
|
|
7358
|
+
in: path
|
|
7359
|
+
required: true
|
|
7360
|
+
schema: { type: string, example: ethereum }
|
|
7361
|
+
- name: X-Auth-Confirm
|
|
7362
|
+
in: header
|
|
7363
|
+
required: true
|
|
7364
|
+
schema: { type: string }
|
|
7365
|
+
description: Account password, or a `rat_` token from `POST /v1/auth/reauth/complete`.
|
|
7366
|
+
requestBody:
|
|
7367
|
+
required: true
|
|
7368
|
+
content:
|
|
7369
|
+
application/json:
|
|
7370
|
+
schema:
|
|
7371
|
+
type: object
|
|
7372
|
+
required: [message]
|
|
7373
|
+
properties:
|
|
7374
|
+
message:
|
|
7375
|
+
type: string
|
|
7376
|
+
maxLength: 16384
|
|
7377
|
+
example: Sign in to Example at 2026-10-01T10:00:00Z
|
|
7378
|
+
responses:
|
|
7379
|
+
'200':
|
|
7380
|
+
description: Signature
|
|
7381
|
+
content:
|
|
7382
|
+
application/json:
|
|
7383
|
+
schema:
|
|
7384
|
+
$ref: '#/components/schemas/WalletSignature'
|
|
7385
|
+
'400':
|
|
7386
|
+
description: Empty or oversized message, or a non-EVM chain
|
|
7387
|
+
'403':
|
|
7388
|
+
description: >
|
|
7389
|
+
Agent caller, missing or insufficient step-up, denied by a
|
|
7390
|
+
wallet access policy, or a self-custody wallet the server
|
|
7391
|
+
cannot sign for.
|
|
7392
|
+
'404':
|
|
7393
|
+
description: No wallet on that chain for this user
|
|
7394
|
+
/v1/treasury/wallets/{chain}/sign-typed-data:
|
|
7395
|
+
post:
|
|
7396
|
+
tags: [Treasury]
|
|
7397
|
+
summary: "Sign EIP-712 typed data with a human wallet"
|
|
7398
|
+
description: >
|
|
7399
|
+
Hashes and signs a full EIP-712 payload. Include
|
|
7400
|
+
`EIP712Domain` in `types` — viem and ethers synthesise that
|
|
7401
|
+
entry and omit it, and this hashes exactly what you send.
|
|
7402
|
+
|
|
7403
|
+
|
|
7404
|
+
Same gates as `sign-message`.
|
|
7405
|
+
operationId: signTreasuryTypedData
|
|
7406
|
+
parameters:
|
|
7407
|
+
- name: chain
|
|
7408
|
+
in: path
|
|
7409
|
+
required: true
|
|
7410
|
+
schema: { type: string, example: base }
|
|
7411
|
+
- name: X-Auth-Confirm
|
|
7412
|
+
in: header
|
|
7413
|
+
required: true
|
|
7414
|
+
schema: { type: string }
|
|
7415
|
+
requestBody:
|
|
7416
|
+
required: true
|
|
7417
|
+
content:
|
|
7418
|
+
application/json:
|
|
7419
|
+
schema:
|
|
7420
|
+
type: object
|
|
7421
|
+
required: [typed_data]
|
|
7422
|
+
properties:
|
|
7423
|
+
typed_data:
|
|
7424
|
+
type: object
|
|
7425
|
+
description: '`types`, `primaryType`, `domain`, `message`.'
|
|
7426
|
+
responses:
|
|
7427
|
+
'200':
|
|
7428
|
+
description: Signature
|
|
7429
|
+
content:
|
|
7430
|
+
application/json:
|
|
7431
|
+
schema:
|
|
7432
|
+
$ref: '#/components/schemas/WalletSignature'
|
|
7433
|
+
'400':
|
|
7434
|
+
description: Malformed EIP-712 payload, or a non-EVM chain
|
|
7435
|
+
'403':
|
|
7436
|
+
description: Same refusals as sign-message
|
|
7437
|
+
'404':
|
|
7438
|
+
description: No wallet on that chain for this user
|
|
7210
7439
|
/v1/treasury/wallets/{chain}/swap:
|
|
7211
7440
|
post:
|
|
7212
7441
|
tags: [Treasury Wallets]
|
|
@@ -11159,6 +11388,113 @@ paths:
|
|
|
11159
11388
|
"429":
|
|
11160
11389
|
description: Rate limited
|
|
11161
11390
|
|
|
11391
|
+
/v1/auth/siwe/challenge:
|
|
11392
|
+
post:
|
|
11393
|
+
tags: [Authentication]
|
|
11394
|
+
summary: Start wallet sign-in (SIWE)
|
|
11395
|
+
description: |
|
|
11396
|
+
Returns the exact EIP-4361 message to sign, for signing in to the
|
|
11397
|
+
dashboard with an Ethereum wallet.
|
|
11398
|
+
|
|
11399
|
+
The message is built server-side and returned whole: the domain and
|
|
11400
|
+
the nonce are ours to decide, and a client that assembles its own
|
|
11401
|
+
message is a client that can be talked into signing a different
|
|
11402
|
+
one. Sign it unmodified and post it back to
|
|
11403
|
+
`/v1/auth/siwe/verify`.
|
|
11404
|
+
|
|
11405
|
+
The nonce is single-use and valid for five minutes. Distinct from
|
|
11406
|
+
`/v1/platform/siwe/challenge`, which needs a `plt_` caller and
|
|
11407
|
+
issues nonces scoped to one platform app for *its* end users.
|
|
11408
|
+
operationId: siweLoginChallenge
|
|
11409
|
+
security: []
|
|
11410
|
+
requestBody:
|
|
11411
|
+
required: true
|
|
11412
|
+
content:
|
|
11413
|
+
application/json:
|
|
11414
|
+
schema:
|
|
11415
|
+
type: object
|
|
11416
|
+
required: [address]
|
|
11417
|
+
properties:
|
|
11418
|
+
address:
|
|
11419
|
+
type: string
|
|
11420
|
+
description: 0x-prefixed 20-byte Ethereum address
|
|
11421
|
+
example: "0x0000000000000000000000000000000000000001"
|
|
11422
|
+
responses:
|
|
11423
|
+
"200":
|
|
11424
|
+
description: Message to sign
|
|
11425
|
+
content:
|
|
11426
|
+
application/json:
|
|
11427
|
+
schema:
|
|
11428
|
+
type: object
|
|
11429
|
+
properties:
|
|
11430
|
+
message:
|
|
11431
|
+
type: string
|
|
11432
|
+
description: Sign this verbatim
|
|
11433
|
+
nonce: { type: string }
|
|
11434
|
+
expires_in_secs: { type: integer }
|
|
11435
|
+
"400":
|
|
11436
|
+
description: Not a valid Ethereum address
|
|
11437
|
+
"429":
|
|
11438
|
+
description: Rate limited
|
|
11439
|
+
|
|
11440
|
+
/v1/auth/siwe/verify:
|
|
11441
|
+
post:
|
|
11442
|
+
tags: [Authentication]
|
|
11443
|
+
summary: Complete wallet sign-in and get a JWT
|
|
11444
|
+
description: |
|
|
11445
|
+
Verifies the signature over the challenge message and returns an
|
|
11446
|
+
ordinary user JWT — the same token social login and email-OTP
|
|
11447
|
+
produce.
|
|
11448
|
+
|
|
11449
|
+
First sign-in for an address creates a user and org. That user's
|
|
11450
|
+
email starts synthetic (`email_pending: true`) and unverified: a
|
|
11451
|
+
wallet signature proves possession of a key, not a reachable
|
|
11452
|
+
person. Staking redemption refuses until a real address is added
|
|
11453
|
+
and confirmed.
|
|
11454
|
+
|
|
11455
|
+
The wallet recovered from the signature is stored on the account
|
|
11456
|
+
and is the identity staking points are counted against. It is
|
|
11457
|
+
never accepted from a request body anywhere.
|
|
11458
|
+
operationId: siweLoginVerify
|
|
11459
|
+
security: []
|
|
11460
|
+
requestBody:
|
|
11461
|
+
required: true
|
|
11462
|
+
content:
|
|
11463
|
+
application/json:
|
|
11464
|
+
schema:
|
|
11465
|
+
type: object
|
|
11466
|
+
required: [message, signature]
|
|
11467
|
+
properties:
|
|
11468
|
+
message:
|
|
11469
|
+
type: string
|
|
11470
|
+
description: The challenge message, unmodified
|
|
11471
|
+
signature:
|
|
11472
|
+
type: string
|
|
11473
|
+
description: Hex signature over the message
|
|
11474
|
+
responses:
|
|
11475
|
+
"200":
|
|
11476
|
+
description: Authenticated
|
|
11477
|
+
content:
|
|
11478
|
+
application/json:
|
|
11479
|
+
schema:
|
|
11480
|
+
type: object
|
|
11481
|
+
properties:
|
|
11482
|
+
token: { type: string }
|
|
11483
|
+
user_id: { type: string, format: uuid }
|
|
11484
|
+
org_id: { type: string, format: uuid }
|
|
11485
|
+
wallet_address: { type: string }
|
|
11486
|
+
is_new_user: { type: boolean }
|
|
11487
|
+
email_pending:
|
|
11488
|
+
type: boolean
|
|
11489
|
+
description: |
|
|
11490
|
+
True while the account email is still the synthetic
|
|
11491
|
+
wallet address. Redemption is blocked until a real
|
|
11492
|
+
one is verified.
|
|
11493
|
+
"400":
|
|
11494
|
+
description: Expired or reused challenge, or a message signed for another domain
|
|
11495
|
+
"401":
|
|
11496
|
+
description: Signature does not match the address in the message
|
|
11497
|
+
|
|
11162
11498
|
# ---------------------------------------------------------------------------
|
|
11163
11499
|
# OAuth
|
|
11164
11500
|
# ---------------------------------------------------------------------------
|
|
@@ -18279,8 +18615,22 @@ paths:
|
|
|
18279
18615
|
the read grant could not be written —
|
|
18280
18616
|
the agent will need access granted
|
|
18281
18617
|
by hand.
|
|
18618
|
+
bound_new_vault:
|
|
18619
|
+
type: boolean
|
|
18620
|
+
description: >
|
|
18621
|
+
True when the agent had to be bound to
|
|
18622
|
+
a vault it was not bound to before. Its
|
|
18623
|
+
access is correct from now on, but a
|
|
18624
|
+
JWT carries the `vault_ids` it was
|
|
18625
|
+
minted with, so a token the agent
|
|
18626
|
+
already holds is refused until it
|
|
18627
|
+
re-mints. Answering into a vault the
|
|
18628
|
+
agent already reaches avoids this.
|
|
18282
18629
|
'400':
|
|
18283
|
-
description:
|
|
18630
|
+
description: >
|
|
18631
|
+
Already answered, expired, an invalid path, or nothing is
|
|
18632
|
+
stored at that path — the location the agent is sent to has
|
|
18633
|
+
to be real.
|
|
18284
18634
|
'403':
|
|
18285
18635
|
description: Called by an agent
|
|
18286
18636
|
'404':
|
|
@@ -27298,6 +27648,18 @@ components:
|
|
|
27298
27648
|
an approval by reply.
|
|
27299
27649
|
created_at: { type: string, format: date-time }
|
|
27300
27650
|
|
|
27651
|
+
WalletSignature:
|
|
27652
|
+
type: object
|
|
27653
|
+
required: [signature, address, chain]
|
|
27654
|
+
properties:
|
|
27655
|
+
signature:
|
|
27656
|
+
type: string
|
|
27657
|
+
description: 65-byte `0x`-prefixed signature, r‖s‖v.
|
|
27658
|
+
address:
|
|
27659
|
+
type: string
|
|
27660
|
+
description: The signing wallet, so it can be passed straight to `verifyMessage`.
|
|
27661
|
+
chain: { type: string }
|
|
27662
|
+
|
|
27301
27663
|
SecretRequest:
|
|
27302
27664
|
type: object
|
|
27303
27665
|
description: >
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1claw/openapi-spec",
|
|
3
|
-
"version": "0.61.
|
|
4
|
-
"description": "OpenAPI 3.1.0 specification for the 1Claw Vault API
|
|
3
|
+
"version": "0.61.49",
|
|
4
|
+
"description": "OpenAPI 3.1.0 specification for the 1Claw Vault API \u2014 generate clients in any language",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|