@1claw/openapi-spec 0.61.46 → 0.61.48

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.
Files changed (3) hide show
  1. package/openapi.json +561 -1
  2. package/openapi.yaml +395 -1
  3. package/package.json +1 -1
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.46",
5
+ "version": "0.61.48",
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"
@@ -11372,6 +11372,146 @@
11372
11372
  }
11373
11373
  }
11374
11374
  },
11375
+ "/v1/treasury/wallets/{chain}/sign-message": {
11376
+ "post": {
11377
+ "tags": [
11378
+ "Treasury"
11379
+ ],
11380
+ "summary": "Sign a message with a human wallet (EIP-191)",
11381
+ "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",
11382
+ "operationId": "signTreasuryMessage",
11383
+ "parameters": [
11384
+ {
11385
+ "name": "chain",
11386
+ "in": "path",
11387
+ "required": true,
11388
+ "schema": {
11389
+ "type": "string",
11390
+ "example": "ethereum"
11391
+ }
11392
+ },
11393
+ {
11394
+ "name": "X-Auth-Confirm",
11395
+ "in": "header",
11396
+ "required": true,
11397
+ "schema": {
11398
+ "type": "string"
11399
+ },
11400
+ "description": "Account password, or a `rat_` token from `POST /v1/auth/reauth/complete`."
11401
+ }
11402
+ ],
11403
+ "requestBody": {
11404
+ "required": true,
11405
+ "content": {
11406
+ "application/json": {
11407
+ "schema": {
11408
+ "type": "object",
11409
+ "required": [
11410
+ "message"
11411
+ ],
11412
+ "properties": {
11413
+ "message": {
11414
+ "type": "string",
11415
+ "maxLength": 16384,
11416
+ "example": "Sign in to Example at 2026-10-01T10:00:00Z"
11417
+ }
11418
+ }
11419
+ }
11420
+ }
11421
+ }
11422
+ },
11423
+ "responses": {
11424
+ "200": {
11425
+ "description": "Signature",
11426
+ "content": {
11427
+ "application/json": {
11428
+ "schema": {
11429
+ "$ref": "#/components/schemas/WalletSignature"
11430
+ }
11431
+ }
11432
+ }
11433
+ },
11434
+ "400": {
11435
+ "description": "Empty or oversized message, or a non-EVM chain"
11436
+ },
11437
+ "403": {
11438
+ "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"
11439
+ },
11440
+ "404": {
11441
+ "description": "No wallet on that chain for this user"
11442
+ }
11443
+ }
11444
+ }
11445
+ },
11446
+ "/v1/treasury/wallets/{chain}/sign-typed-data": {
11447
+ "post": {
11448
+ "tags": [
11449
+ "Treasury"
11450
+ ],
11451
+ "summary": "Sign EIP-712 typed data with a human wallet",
11452
+ "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",
11453
+ "operationId": "signTreasuryTypedData",
11454
+ "parameters": [
11455
+ {
11456
+ "name": "chain",
11457
+ "in": "path",
11458
+ "required": true,
11459
+ "schema": {
11460
+ "type": "string",
11461
+ "example": "base"
11462
+ }
11463
+ },
11464
+ {
11465
+ "name": "X-Auth-Confirm",
11466
+ "in": "header",
11467
+ "required": true,
11468
+ "schema": {
11469
+ "type": "string"
11470
+ }
11471
+ }
11472
+ ],
11473
+ "requestBody": {
11474
+ "required": true,
11475
+ "content": {
11476
+ "application/json": {
11477
+ "schema": {
11478
+ "type": "object",
11479
+ "required": [
11480
+ "typed_data"
11481
+ ],
11482
+ "properties": {
11483
+ "typed_data": {
11484
+ "type": "object",
11485
+ "description": "`types`, `primaryType`, `domain`, `message`."
11486
+ }
11487
+ }
11488
+ }
11489
+ }
11490
+ }
11491
+ },
11492
+ "responses": {
11493
+ "200": {
11494
+ "description": "Signature",
11495
+ "content": {
11496
+ "application/json": {
11497
+ "schema": {
11498
+ "$ref": "#/components/schemas/WalletSignature"
11499
+ }
11500
+ }
11501
+ }
11502
+ },
11503
+ "400": {
11504
+ "description": "Malformed EIP-712 payload, or a non-EVM chain"
11505
+ },
11506
+ "403": {
11507
+ "description": "Same refusals as sign-message"
11508
+ },
11509
+ "404": {
11510
+ "description": "No wallet on that chain for this user"
11511
+ }
11512
+ }
11513
+ }
11514
+ },
11375
11515
  "/v1/treasury/wallets/{chain}/swap": {
11376
11516
  "post": {
11377
11517
  "tags": [
@@ -28340,6 +28480,301 @@
28340
28480
  }
28341
28481
  }
28342
28482
  },
28483
+ "/v1/secret-requests": {
28484
+ "post": {
28485
+ "tags": [
28486
+ "Secrets"
28487
+ ],
28488
+ "summary": "Ask a human for a credential",
28489
+ "description": "Agent-authenticated. The agent says what it needs and why; the human sees a secure field in the dashboard, stores the value straight into the vault over their own session, and the agent is later told **where** it went — never what it is.\n\nThis exists because the alternative is worse than it looks. Typing a credential into runtime chat persists it to the conversation, writes it into the agent's memory, and replays it to the model on every later turn: one paste, four copies, no way back.\n\nOne open request per agent per label: asking again with the same label refreshes the existing one rather than queueing a duplicate. Unanswered requests expire after 24 hours.\n",
28490
+ "operationId": "create_secret_request",
28491
+ "requestBody": {
28492
+ "required": true,
28493
+ "content": {
28494
+ "application/json": {
28495
+ "schema": {
28496
+ "type": "object",
28497
+ "required": [
28498
+ "label",
28499
+ "purpose"
28500
+ ],
28501
+ "properties": {
28502
+ "label": {
28503
+ "type": "string",
28504
+ "maxLength": 120,
28505
+ "example": "X API access token"
28506
+ },
28507
+ "purpose": {
28508
+ "type": "string",
28509
+ "maxLength": 500,
28510
+ "description": "Shown to the person being asked. They are handing over a secret and need to know what for.\n",
28511
+ "example": "To post the daily update to X on your behalf."
28512
+ },
28513
+ "suggested_path": {
28514
+ "type": "string",
28515
+ "nullable": true,
28516
+ "description": "A suggestion only — the human picks the vault and may change the path.\n",
28517
+ "example": "api-keys/x-access-token"
28518
+ }
28519
+ }
28520
+ }
28521
+ }
28522
+ }
28523
+ },
28524
+ "responses": {
28525
+ "202": {
28526
+ "description": "Asked. Poll the status route; do not ask in conversation.",
28527
+ "content": {
28528
+ "application/json": {
28529
+ "schema": {
28530
+ "type": "object",
28531
+ "required": [
28532
+ "id",
28533
+ "status",
28534
+ "expires_at",
28535
+ "next"
28536
+ ],
28537
+ "properties": {
28538
+ "id": {
28539
+ "type": "string",
28540
+ "format": "uuid"
28541
+ },
28542
+ "status": {
28543
+ "type": "string",
28544
+ "example": "pending"
28545
+ },
28546
+ "expires_at": {
28547
+ "type": "string",
28548
+ "format": "date-time"
28549
+ },
28550
+ "next": {
28551
+ "type": "string"
28552
+ }
28553
+ }
28554
+ }
28555
+ }
28556
+ }
28557
+ },
28558
+ "400": {
28559
+ "description": "Missing label or purpose, or an invalid suggested path"
28560
+ },
28561
+ "403": {
28562
+ "description": "Not an agent. A person storing a credential uses the vault directly.\n"
28563
+ }
28564
+ }
28565
+ },
28566
+ "get": {
28567
+ "tags": [
28568
+ "Secrets"
28569
+ ],
28570
+ "summary": "What your agents have asked you for",
28571
+ "description": "User-authenticated. Open requests for the caller's org, newest first, excluding expired ones. Agents cannot call this — they read their own request by id, so one agent can never enumerate which credentials an org holds.\n",
28572
+ "operationId": "list_secret_requests",
28573
+ "responses": {
28574
+ "200": {
28575
+ "description": "Open requests",
28576
+ "content": {
28577
+ "application/json": {
28578
+ "schema": {
28579
+ "type": "object",
28580
+ "required": [
28581
+ "requests"
28582
+ ],
28583
+ "properties": {
28584
+ "requests": {
28585
+ "type": "array",
28586
+ "items": {
28587
+ "$ref": "#/components/schemas/SecretRequest"
28588
+ }
28589
+ }
28590
+ }
28591
+ }
28592
+ }
28593
+ }
28594
+ },
28595
+ "403": {
28596
+ "description": "Called by an agent"
28597
+ }
28598
+ }
28599
+ }
28600
+ },
28601
+ "/v1/secret-requests/{id}": {
28602
+ "get": {
28603
+ "tags": [
28604
+ "Secrets"
28605
+ ],
28606
+ "summary": "Has my human answered yet?",
28607
+ "description": "The asking agent's own view, and only its own — another agent's request reads as 404 rather than 403, so its existence is not disclosed. A fulfilled request returns a vault id and a path; the value is read separately with `get_secret`.\n\nExpiry is computed on read, so a lapsed request cannot appear live because no sweeper has run.\n",
28608
+ "operationId": "get_secret_request",
28609
+ "parameters": [
28610
+ {
28611
+ "name": "id",
28612
+ "in": "path",
28613
+ "required": true,
28614
+ "schema": {
28615
+ "type": "string",
28616
+ "format": "uuid"
28617
+ }
28618
+ }
28619
+ ],
28620
+ "responses": {
28621
+ "200": {
28622
+ "description": "Status and, once fulfilled, where to look",
28623
+ "content": {
28624
+ "application/json": {
28625
+ "schema": {
28626
+ "$ref": "#/components/schemas/SecretRequestAgentView"
28627
+ }
28628
+ }
28629
+ }
28630
+ },
28631
+ "404": {
28632
+ "description": "No such request, or it belongs to another agent"
28633
+ }
28634
+ }
28635
+ }
28636
+ },
28637
+ "/v1/secret-requests/{id}/fulfil": {
28638
+ "post": {
28639
+ "tags": [
28640
+ "Secrets"
28641
+ ],
28642
+ "summary": "Tell the agent where you put it",
28643
+ "description": "User-authenticated. Takes a **location, never a value** — by the time this is called the secret is already in the vault, written by the browser with `PUT /v1/vaults/{vault_id}/secrets/{path}` over the user's own session. There is no field here that could carry a plaintext credential, and there should never be one.\n\nFulfilment also grants the asking agent read on exactly that path, and binds the vault to it if the agent has an explicit vault list. Without both, the user hands over a credential and the agent still gets a 403 — the failure this whole flow exists to remove.\n",
28644
+ "operationId": "fulfil_secret_request",
28645
+ "parameters": [
28646
+ {
28647
+ "name": "id",
28648
+ "in": "path",
28649
+ "required": true,
28650
+ "schema": {
28651
+ "type": "string",
28652
+ "format": "uuid"
28653
+ }
28654
+ }
28655
+ ],
28656
+ "requestBody": {
28657
+ "required": true,
28658
+ "content": {
28659
+ "application/json": {
28660
+ "schema": {
28661
+ "type": "object",
28662
+ "required": [
28663
+ "vault_id",
28664
+ "path"
28665
+ ],
28666
+ "properties": {
28667
+ "vault_id": {
28668
+ "type": "string",
28669
+ "format": "uuid"
28670
+ },
28671
+ "path": {
28672
+ "type": "string",
28673
+ "example": "api-keys/x-access-token"
28674
+ }
28675
+ }
28676
+ }
28677
+ }
28678
+ }
28679
+ },
28680
+ "responses": {
28681
+ "200": {
28682
+ "description": "Fulfilled",
28683
+ "content": {
28684
+ "application/json": {
28685
+ "schema": {
28686
+ "type": "object",
28687
+ "required": [
28688
+ "status",
28689
+ "path",
28690
+ "vault_id",
28691
+ "granted_read"
28692
+ ],
28693
+ "properties": {
28694
+ "status": {
28695
+ "type": "string",
28696
+ "example": "fulfilled"
28697
+ },
28698
+ "path": {
28699
+ "type": "string"
28700
+ },
28701
+ "vault_id": {
28702
+ "type": "string",
28703
+ "format": "uuid"
28704
+ },
28705
+ "granted_read": {
28706
+ "type": "boolean",
28707
+ "description": "False when the secret was stored but the read grant could not be written — the agent will need access granted by hand.\n"
28708
+ },
28709
+ "bound_new_vault": {
28710
+ "type": "boolean",
28711
+ "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"
28712
+ }
28713
+ }
28714
+ }
28715
+ }
28716
+ }
28717
+ },
28718
+ "400": {
28719
+ "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"
28720
+ },
28721
+ "403": {
28722
+ "description": "Called by an agent"
28723
+ },
28724
+ "404": {
28725
+ "description": "No such request, or no such vault in this org"
28726
+ }
28727
+ }
28728
+ }
28729
+ },
28730
+ "/v1/secret-requests/{id}/decline": {
28731
+ "post": {
28732
+ "tags": [
28733
+ "Secrets"
28734
+ ],
28735
+ "summary": "No, and stop asking",
28736
+ "description": "User-authenticated. The agent's next poll returns `declined` with an instruction not to ask again for the same thing and to say plainly what it cannot do.\n",
28737
+ "operationId": "decline_secret_request",
28738
+ "parameters": [
28739
+ {
28740
+ "name": "id",
28741
+ "in": "path",
28742
+ "required": true,
28743
+ "schema": {
28744
+ "type": "string",
28745
+ "format": "uuid"
28746
+ }
28747
+ }
28748
+ ],
28749
+ "responses": {
28750
+ "200": {
28751
+ "description": "Declined",
28752
+ "content": {
28753
+ "application/json": {
28754
+ "schema": {
28755
+ "type": "object",
28756
+ "required": [
28757
+ "status"
28758
+ ],
28759
+ "properties": {
28760
+ "status": {
28761
+ "type": "string",
28762
+ "example": "declined"
28763
+ }
28764
+ }
28765
+ }
28766
+ }
28767
+ }
28768
+ },
28769
+ "400": {
28770
+ "description": "Already answered"
28771
+ },
28772
+ "403": {
28773
+ "description": "Called by an agent"
28774
+ }
28775
+ }
28776
+ }
28777
+ },
28343
28778
  "/v1/billing/promo/preview": {
28344
28779
  "get": {
28345
28780
  "tags": [
@@ -42117,6 +42552,131 @@
42117
42552
  }
42118
42553
  }
42119
42554
  },
42555
+ "WalletSignature": {
42556
+ "type": "object",
42557
+ "required": [
42558
+ "signature",
42559
+ "address",
42560
+ "chain"
42561
+ ],
42562
+ "properties": {
42563
+ "signature": {
42564
+ "type": "string",
42565
+ "description": "65-byte `0x`-prefixed signature, r‖s‖v."
42566
+ },
42567
+ "address": {
42568
+ "type": "string",
42569
+ "description": "The signing wallet, so it can be passed straight to `verifyMessage`."
42570
+ },
42571
+ "chain": {
42572
+ "type": "string"
42573
+ }
42574
+ }
42575
+ },
42576
+ "SecretRequest": {
42577
+ "type": "object",
42578
+ "description": "An agent's open ask, as the human sees it. Carries the request and, once fulfilled, a reference — never a value.\n",
42579
+ "required": [
42580
+ "id",
42581
+ "label",
42582
+ "purpose",
42583
+ "status",
42584
+ "expires_at",
42585
+ "created_at"
42586
+ ],
42587
+ "properties": {
42588
+ "id": {
42589
+ "type": "string",
42590
+ "format": "uuid"
42591
+ },
42592
+ "agent_id": {
42593
+ "type": "string",
42594
+ "format": "uuid",
42595
+ "nullable": true
42596
+ },
42597
+ "agent_name": {
42598
+ "type": "string",
42599
+ "nullable": true
42600
+ },
42601
+ "label": {
42602
+ "type": "string",
42603
+ "description": "Written by the agent. Untrusted text — render it as text, never as markup.\n"
42604
+ },
42605
+ "purpose": {
42606
+ "type": "string"
42607
+ },
42608
+ "suggested_path": {
42609
+ "type": "string",
42610
+ "nullable": true
42611
+ },
42612
+ "status": {
42613
+ "type": "string",
42614
+ "enum": [
42615
+ "pending",
42616
+ "fulfilled",
42617
+ "declined",
42618
+ "expired"
42619
+ ]
42620
+ },
42621
+ "stored_path": {
42622
+ "type": "string",
42623
+ "nullable": true,
42624
+ "description": "Set on fulfilment. Where the secret went, not what it is."
42625
+ },
42626
+ "vault_id": {
42627
+ "type": "string",
42628
+ "format": "uuid",
42629
+ "nullable": true
42630
+ },
42631
+ "expires_at": {
42632
+ "type": "string",
42633
+ "format": "date-time"
42634
+ },
42635
+ "created_at": {
42636
+ "type": "string",
42637
+ "format": "date-time"
42638
+ }
42639
+ }
42640
+ },
42641
+ "SecretRequestAgentView": {
42642
+ "type": "object",
42643
+ "description": "The same request as the *agent* is allowed to see it: status, and once fulfilled where to look. Deliberately narrower than `SecretRequest` — no `fulfilled_by`, no timestamps, and no field anywhere that could hold a credential.\n",
42644
+ "required": [
42645
+ "id",
42646
+ "status",
42647
+ "next"
42648
+ ],
42649
+ "properties": {
42650
+ "id": {
42651
+ "type": "string",
42652
+ "format": "uuid"
42653
+ },
42654
+ "status": {
42655
+ "type": "string",
42656
+ "enum": [
42657
+ "pending",
42658
+ "fulfilled",
42659
+ "declined",
42660
+ "expired"
42661
+ ]
42662
+ },
42663
+ "vault_id": {
42664
+ "type": "string",
42665
+ "format": "uuid",
42666
+ "nullable": true,
42667
+ "description": "Present only once fulfilled."
42668
+ },
42669
+ "path": {
42670
+ "type": "string",
42671
+ "nullable": true,
42672
+ "description": "Present only once fulfilled. Read the credential from here with `get_secret`.\n"
42673
+ },
42674
+ "next": {
42675
+ "type": "string",
42676
+ "description": "What to do about this status, in the agent's terms."
42677
+ }
42678
+ }
42679
+ },
42120
42680
  "ConnectorPreset": {
42121
42681
  "type": "object",
42122
42682
  "required": [
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.46"
5
+ version: "0.61.48"
6
6
  description: |
7
7
  Secure secret management for AI agents. Provides vaults, secrets,
8
8
  policy-based access control, agent identity, Intents API,
@@ -7207,6 +7207,109 @@ paths:
7207
7207
  "404":
7208
7208
  $ref: "#/components/responses/NotFound"
7209
7209
 
7210
+ /v1/treasury/wallets/{chain}/sign-message:
7211
+ post:
7212
+ tags: [Treasury]
7213
+ summary: "Sign a message with a human wallet (EIP-191)"
7214
+ description: >
7215
+ `personal_sign` over the given text, hashed as
7216
+ `\x19Ethereum Signed Message:\n<len>` + message — what
7217
+ viem's `verifyMessage` and ethers' `verifyMessage` expect.
7218
+
7219
+
7220
+ Human callers only; an agent signs with its own key via
7221
+ `POST /v1/agents/{agent_id}/sign`. Gated exactly as a send
7222
+ is: `X-Auth-Confirm` step-up scored as a Send action, wallet
7223
+ access policies (`WalletAction::Sign`), and a refusal for
7224
+ wallets whose key is split or passkey-owned — those have no
7225
+ server-side key and will not fall back to one.
7226
+
7227
+
7228
+ EVM chains only.
7229
+ operationId: signTreasuryMessage
7230
+ parameters:
7231
+ - name: chain
7232
+ in: path
7233
+ required: true
7234
+ schema: { type: string, example: ethereum }
7235
+ - name: X-Auth-Confirm
7236
+ in: header
7237
+ required: true
7238
+ schema: { type: string }
7239
+ description: Account password, or a `rat_` token from `POST /v1/auth/reauth/complete`.
7240
+ requestBody:
7241
+ required: true
7242
+ content:
7243
+ application/json:
7244
+ schema:
7245
+ type: object
7246
+ required: [message]
7247
+ properties:
7248
+ message:
7249
+ type: string
7250
+ maxLength: 16384
7251
+ example: Sign in to Example at 2026-10-01T10:00:00Z
7252
+ responses:
7253
+ '200':
7254
+ description: Signature
7255
+ content:
7256
+ application/json:
7257
+ schema:
7258
+ $ref: '#/components/schemas/WalletSignature'
7259
+ '400':
7260
+ description: Empty or oversized message, or a non-EVM chain
7261
+ '403':
7262
+ description: >
7263
+ Agent caller, missing or insufficient step-up, denied by a
7264
+ wallet access policy, or a self-custody wallet the server
7265
+ cannot sign for.
7266
+ '404':
7267
+ description: No wallet on that chain for this user
7268
+ /v1/treasury/wallets/{chain}/sign-typed-data:
7269
+ post:
7270
+ tags: [Treasury]
7271
+ summary: "Sign EIP-712 typed data with a human wallet"
7272
+ description: >
7273
+ Hashes and signs a full EIP-712 payload. Include
7274
+ `EIP712Domain` in `types` — viem and ethers synthesise that
7275
+ entry and omit it, and this hashes exactly what you send.
7276
+
7277
+
7278
+ Same gates as `sign-message`.
7279
+ operationId: signTreasuryTypedData
7280
+ parameters:
7281
+ - name: chain
7282
+ in: path
7283
+ required: true
7284
+ schema: { type: string, example: base }
7285
+ - name: X-Auth-Confirm
7286
+ in: header
7287
+ required: true
7288
+ schema: { type: string }
7289
+ requestBody:
7290
+ required: true
7291
+ content:
7292
+ application/json:
7293
+ schema:
7294
+ type: object
7295
+ required: [typed_data]
7296
+ properties:
7297
+ typed_data:
7298
+ type: object
7299
+ description: '`types`, `primaryType`, `domain`, `message`.'
7300
+ responses:
7301
+ '200':
7302
+ description: Signature
7303
+ content:
7304
+ application/json:
7305
+ schema:
7306
+ $ref: '#/components/schemas/WalletSignature'
7307
+ '400':
7308
+ description: Malformed EIP-712 payload, or a non-EVM chain
7309
+ '403':
7310
+ description: Same refusals as sign-message
7311
+ '404':
7312
+ description: No wallet on that chain for this user
7210
7313
  /v1/treasury/wallets/{chain}/swap:
7211
7314
  post:
7212
7315
  tags: [Treasury Wallets]
@@ -18104,6 +18207,229 @@ paths:
18104
18207
  - $ref: '#/components/schemas/ConnectorPreset'
18105
18208
  '401':
18106
18209
  description: Unauthenticated
18210
+ /v1/secret-requests:
18211
+ post:
18212
+ tags: [Secrets]
18213
+ summary: "Ask a human for a credential"
18214
+ description: >
18215
+ Agent-authenticated. The agent says what it needs and why; the
18216
+ human sees a secure field in the dashboard, stores the value
18217
+ straight into the vault over their own session, and the agent
18218
+ is later told **where** it went — never what it is.
18219
+
18220
+
18221
+ This exists because the alternative is worse than it looks.
18222
+ Typing a credential into runtime chat persists it to the
18223
+ conversation, writes it into the agent's memory, and replays it
18224
+ to the model on every later turn: one paste, four copies, no
18225
+ way back.
18226
+
18227
+
18228
+ One open request per agent per label: asking again with the
18229
+ same label refreshes the existing one rather than queueing a
18230
+ duplicate. Unanswered requests expire after 24 hours.
18231
+ operationId: create_secret_request
18232
+ requestBody:
18233
+ required: true
18234
+ content:
18235
+ application/json:
18236
+ schema:
18237
+ type: object
18238
+ required: [label, purpose]
18239
+ properties:
18240
+ label:
18241
+ type: string
18242
+ maxLength: 120
18243
+ example: X API access token
18244
+ purpose:
18245
+ type: string
18246
+ maxLength: 500
18247
+ description: >
18248
+ Shown to the person being asked. They are
18249
+ handing over a secret and need to know
18250
+ what for.
18251
+ example: To post the daily update to X on your behalf.
18252
+ suggested_path:
18253
+ type: string
18254
+ nullable: true
18255
+ description: >
18256
+ A suggestion only — the human picks the
18257
+ vault and may change the path.
18258
+ example: api-keys/x-access-token
18259
+ responses:
18260
+ '202':
18261
+ description: Asked. Poll the status route; do not ask in conversation.
18262
+ content:
18263
+ application/json:
18264
+ schema:
18265
+ type: object
18266
+ required: [id, status, expires_at, next]
18267
+ properties:
18268
+ id: { type: string, format: uuid }
18269
+ status: { type: string, example: pending }
18270
+ expires_at: { type: string, format: date-time }
18271
+ next: { type: string }
18272
+ '400':
18273
+ description: Missing label or purpose, or an invalid suggested path
18274
+ '403':
18275
+ description: >
18276
+ Not an agent. A person storing a credential uses the
18277
+ vault directly.
18278
+ get:
18279
+ tags: [Secrets]
18280
+ summary: "What your agents have asked you for"
18281
+ description: >
18282
+ User-authenticated. Open requests for the caller's org, newest
18283
+ first, excluding expired ones. Agents cannot call this — they
18284
+ read their own request by id, so one agent can never enumerate
18285
+ which credentials an org holds.
18286
+ operationId: list_secret_requests
18287
+ responses:
18288
+ '200':
18289
+ description: Open requests
18290
+ content:
18291
+ application/json:
18292
+ schema:
18293
+ type: object
18294
+ required: [requests]
18295
+ properties:
18296
+ requests:
18297
+ type: array
18298
+ items:
18299
+ $ref: '#/components/schemas/SecretRequest'
18300
+ '403':
18301
+ description: Called by an agent
18302
+ /v1/secret-requests/{id}:
18303
+ get:
18304
+ tags: [Secrets]
18305
+ summary: "Has my human answered yet?"
18306
+ description: >
18307
+ The asking agent's own view, and only its own — another agent's
18308
+ request reads as 404 rather than 403, so its existence is not
18309
+ disclosed. A fulfilled request returns a vault id and a path;
18310
+ the value is read separately with `get_secret`.
18311
+
18312
+
18313
+ Expiry is computed on read, so a lapsed request cannot appear
18314
+ live because no sweeper has run.
18315
+ operationId: get_secret_request
18316
+ parameters:
18317
+ - name: id
18318
+ in: path
18319
+ required: true
18320
+ schema: { type: string, format: uuid }
18321
+ responses:
18322
+ '200':
18323
+ description: Status and, once fulfilled, where to look
18324
+ content:
18325
+ application/json:
18326
+ schema:
18327
+ $ref: '#/components/schemas/SecretRequestAgentView'
18328
+ '404':
18329
+ description: No such request, or it belongs to another agent
18330
+ /v1/secret-requests/{id}/fulfil:
18331
+ post:
18332
+ tags: [Secrets]
18333
+ summary: "Tell the agent where you put it"
18334
+ description: >
18335
+ User-authenticated. Takes a **location, never a value** — by
18336
+ the time this is called the secret is already in the vault,
18337
+ written by the browser with
18338
+ `PUT /v1/vaults/{vault_id}/secrets/{path}` over the user's own
18339
+ session. There is no field here that could carry a plaintext
18340
+ credential, and there should never be one.
18341
+
18342
+
18343
+ Fulfilment also grants the asking agent read on exactly that
18344
+ path, and binds the vault to it if the agent has an explicit
18345
+ vault list. Without both, the user hands over a credential and
18346
+ the agent still gets a 403 — the failure this whole flow
18347
+ exists to remove.
18348
+ operationId: fulfil_secret_request
18349
+ parameters:
18350
+ - name: id
18351
+ in: path
18352
+ required: true
18353
+ schema: { type: string, format: uuid }
18354
+ requestBody:
18355
+ required: true
18356
+ content:
18357
+ application/json:
18358
+ schema:
18359
+ type: object
18360
+ required: [vault_id, path]
18361
+ properties:
18362
+ vault_id: { type: string, format: uuid }
18363
+ path:
18364
+ type: string
18365
+ example: api-keys/x-access-token
18366
+ responses:
18367
+ '200':
18368
+ description: Fulfilled
18369
+ content:
18370
+ application/json:
18371
+ schema:
18372
+ type: object
18373
+ required: [status, path, vault_id, granted_read]
18374
+ properties:
18375
+ status: { type: string, example: fulfilled }
18376
+ path: { type: string }
18377
+ vault_id: { type: string, format: uuid }
18378
+ granted_read:
18379
+ type: boolean
18380
+ description: >
18381
+ False when the secret was stored but
18382
+ the read grant could not be written —
18383
+ the agent will need access granted
18384
+ by hand.
18385
+ bound_new_vault:
18386
+ type: boolean
18387
+ description: >
18388
+ True when the agent had to be bound to
18389
+ a vault it was not bound to before. Its
18390
+ access is correct from now on, but a
18391
+ JWT carries the `vault_ids` it was
18392
+ minted with, so a token the agent
18393
+ already holds is refused until it
18394
+ re-mints. Answering into a vault the
18395
+ agent already reaches avoids this.
18396
+ '400':
18397
+ description: >
18398
+ Already answered, expired, an invalid path, or nothing is
18399
+ stored at that path — the location the agent is sent to has
18400
+ to be real.
18401
+ '403':
18402
+ description: Called by an agent
18403
+ '404':
18404
+ description: No such request, or no such vault in this org
18405
+ /v1/secret-requests/{id}/decline:
18406
+ post:
18407
+ tags: [Secrets]
18408
+ summary: "No, and stop asking"
18409
+ description: >
18410
+ User-authenticated. The agent's next poll returns `declined`
18411
+ with an instruction not to ask again for the same thing and to
18412
+ say plainly what it cannot do.
18413
+ operationId: decline_secret_request
18414
+ parameters:
18415
+ - name: id
18416
+ in: path
18417
+ required: true
18418
+ schema: { type: string, format: uuid }
18419
+ responses:
18420
+ '200':
18421
+ description: Declined
18422
+ content:
18423
+ application/json:
18424
+ schema:
18425
+ type: object
18426
+ required: [status]
18427
+ properties:
18428
+ status: { type: string, example: declined }
18429
+ '400':
18430
+ description: Already answered
18431
+ '403':
18432
+ description: Called by an agent
18107
18433
  /v1/billing/promo/preview:
18108
18434
  get:
18109
18435
  tags: [Billing]
@@ -27089,6 +27415,74 @@ components:
27089
27415
  an approval by reply.
27090
27416
  created_at: { type: string, format: date-time }
27091
27417
 
27418
+ WalletSignature:
27419
+ type: object
27420
+ required: [signature, address, chain]
27421
+ properties:
27422
+ signature:
27423
+ type: string
27424
+ description: 65-byte `0x`-prefixed signature, r‖s‖v.
27425
+ address:
27426
+ type: string
27427
+ description: The signing wallet, so it can be passed straight to `verifyMessage`.
27428
+ chain: { type: string }
27429
+
27430
+ SecretRequest:
27431
+ type: object
27432
+ description: >
27433
+ An agent's open ask, as the human sees it. Carries the request
27434
+ and, once fulfilled, a reference — never a value.
27435
+ required: [id, label, purpose, status, expires_at, created_at]
27436
+ properties:
27437
+ id: { type: string, format: uuid }
27438
+ agent_id: { type: string, format: uuid, nullable: true }
27439
+ agent_name: { type: string, nullable: true }
27440
+ label:
27441
+ type: string
27442
+ description: >
27443
+ Written by the agent. Untrusted text — render it as
27444
+ text, never as markup.
27445
+ purpose: { type: string }
27446
+ suggested_path: { type: string, nullable: true }
27447
+ status:
27448
+ type: string
27449
+ enum: [pending, fulfilled, declined, expired]
27450
+ stored_path:
27451
+ type: string
27452
+ nullable: true
27453
+ description: Set on fulfilment. Where the secret went, not what it is.
27454
+ vault_id: { type: string, format: uuid, nullable: true }
27455
+ expires_at: { type: string, format: date-time }
27456
+ created_at: { type: string, format: date-time }
27457
+
27458
+ SecretRequestAgentView:
27459
+ type: object
27460
+ description: >
27461
+ The same request as the *agent* is allowed to see it: status,
27462
+ and once fulfilled where to look. Deliberately narrower than
27463
+ `SecretRequest` — no `fulfilled_by`, no timestamps, and no
27464
+ field anywhere that could hold a credential.
27465
+ required: [id, status, next]
27466
+ properties:
27467
+ id: { type: string, format: uuid }
27468
+ status:
27469
+ type: string
27470
+ enum: [pending, fulfilled, declined, expired]
27471
+ vault_id:
27472
+ type: string
27473
+ format: uuid
27474
+ nullable: true
27475
+ description: Present only once fulfilled.
27476
+ path:
27477
+ type: string
27478
+ nullable: true
27479
+ description: >
27480
+ Present only once fulfilled. Read the credential from
27481
+ here with `get_secret`.
27482
+ next:
27483
+ type: string
27484
+ description: What to do about this status, in the agent's terms.
27485
+
27092
27486
  ConnectorPreset:
27093
27487
  type: object
27094
27488
  required: [slug, display_name, description, category, binding_type, base_url, requires_oauth]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1claw/openapi-spec",
3
- "version": "0.61.46",
3
+ "version": "0.61.48",
4
4
  "description": "OpenAPI 3.1.0 specification for the 1Claw Vault API — generate clients in any language",
5
5
  "license": "MIT",
6
6
  "repository": {