@arke-institute/sdk 2.3.0 → 2.3.1

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/spec.json CHANGED
@@ -1673,6 +1673,135 @@
1673
1673
  "expect_tip"
1674
1674
  ]
1675
1675
  },
1676
+ "EntityDeletedResponse": {
1677
+ "type": "object",
1678
+ "properties": {
1679
+ "id": {
1680
+ "type": "string",
1681
+ "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
1682
+ "description": "Entity ID (ULID format)",
1683
+ "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
1684
+ },
1685
+ "cid": {
1686
+ "type": "string",
1687
+ "minLength": 1,
1688
+ "description": "IPFS Content Identifier (CID)",
1689
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
1690
+ },
1691
+ "deleted_at": {
1692
+ "type": "string",
1693
+ "format": "date-time",
1694
+ "description": "ISO timestamp when the entity was deleted"
1695
+ },
1696
+ "ver": {
1697
+ "type": "integer",
1698
+ "minimum": 0,
1699
+ "exclusiveMinimum": true,
1700
+ "description": "Entity version number",
1701
+ "example": 1
1702
+ },
1703
+ "prev_cid": {
1704
+ "type": "string",
1705
+ "minLength": 1,
1706
+ "description": "IPFS Content Identifier (CID)",
1707
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
1708
+ }
1709
+ },
1710
+ "required": [
1711
+ "id",
1712
+ "cid",
1713
+ "deleted_at",
1714
+ "ver",
1715
+ "prev_cid"
1716
+ ]
1717
+ },
1718
+ "DeleteEntityRequest": {
1719
+ "type": "object",
1720
+ "properties": {
1721
+ "expect_tip": {
1722
+ "type": "string",
1723
+ "minLength": 1,
1724
+ "description": "Current tip CID for CAS validation. Request fails with 409 if this does not match.",
1725
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
1726
+ },
1727
+ "note": {
1728
+ "type": "string",
1729
+ "description": "Optional note describing this change",
1730
+ "example": "Added Chapter 42: The Whiteness of the Whale"
1731
+ },
1732
+ "reason": {
1733
+ "type": "string",
1734
+ "maxLength": 500,
1735
+ "description": "Reason for deleting the entity",
1736
+ "example": "Duplicate entry"
1737
+ }
1738
+ },
1739
+ "required": [
1740
+ "expect_tip"
1741
+ ]
1742
+ },
1743
+ "EntityUpdateResponse": {
1744
+ "allOf": [
1745
+ {
1746
+ "$ref": "#/components/schemas/EntityResponse"
1747
+ },
1748
+ {
1749
+ "type": "object",
1750
+ "properties": {
1751
+ "prev_cid": {
1752
+ "type": "string",
1753
+ "minLength": 1,
1754
+ "description": "Previous version CID",
1755
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
1756
+ }
1757
+ },
1758
+ "required": [
1759
+ "prev_cid"
1760
+ ]
1761
+ }
1762
+ ]
1763
+ },
1764
+ "EntityRestoredResponse": {
1765
+ "allOf": [
1766
+ {
1767
+ "$ref": "#/components/schemas/EntityUpdateResponse"
1768
+ },
1769
+ {
1770
+ "type": "object",
1771
+ "properties": {
1772
+ "restored_from_ver": {
1773
+ "type": "integer",
1774
+ "minimum": 0,
1775
+ "exclusiveMinimum": true,
1776
+ "description": "The version number that was restored from",
1777
+ "example": 1
1778
+ }
1779
+ },
1780
+ "required": [
1781
+ "restored_from_ver"
1782
+ ]
1783
+ }
1784
+ ]
1785
+ },
1786
+ "RestoreEntityRequest": {
1787
+ "type": "object",
1788
+ "properties": {
1789
+ "expect_tip": {
1790
+ "type": "string",
1791
+ "minLength": 1,
1792
+ "description": "Current tip CID for CAS validation. Request fails with 409 if this does not match.",
1793
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
1794
+ },
1795
+ "note": {
1796
+ "type": "string",
1797
+ "description": "Optional note describing this change",
1798
+ "example": "Added Chapter 42: The Whiteness of the Whale"
1799
+ }
1800
+ },
1801
+ "required": [
1802
+ "expect_tip"
1803
+ ]
1804
+ },
1676
1805
  "AddRelationshipResponse": {
1677
1806
  "type": "object",
1678
1807
  "properties": {
@@ -1929,18 +2058,6 @@
1929
2058
  "exclusiveMinimum": true,
1930
2059
  "description": "Unix timestamp in milliseconds",
1931
2060
  "example": 1735214400000
1932
- },
1933
- "upload_url": {
1934
- "type": "string",
1935
- "format": "uri",
1936
- "description": "Presigned S3 URL for uploading file content",
1937
- "example": "https://arke-blocks.s3.amazonaws.com/01JFILE123.../v1?X-Amz-..."
1938
- },
1939
- "upload_expires_at": {
1940
- "type": "string",
1941
- "format": "date-time",
1942
- "description": "When the upload URL expires (15 minutes)",
1943
- "example": "2025-12-26T12:00:00.000Z"
1944
2061
  }
1945
2062
  },
1946
2063
  "required": [
@@ -1951,9 +2068,7 @@
1951
2068
  "relationships",
1952
2069
  "ver",
1953
2070
  "created_at",
1954
- "ts",
1955
- "upload_url",
1956
- "upload_expires_at"
2071
+ "ts"
1957
2072
  ]
1958
2073
  },
1959
2074
  "CreateFileRequest": {
@@ -1962,7 +2077,7 @@
1962
2077
  "key": {
1963
2078
  "type": "string",
1964
2079
  "minLength": 1,
1965
- "description": "Storage key in S3. Best practice: use the CID.",
2080
+ "description": "Storage key in R2. Best practice: use the CID.",
1966
2081
  "example": "bafkreiabc123..."
1967
2082
  },
1968
2083
  "filename": {
@@ -1980,14 +2095,9 @@
1980
2095
  "size": {
1981
2096
  "type": "integer",
1982
2097
  "minimum": 0,
1983
- "description": "File size in bytes",
2098
+ "description": "Expected file size in bytes (verified on upload)",
1984
2099
  "example": 1048576
1985
2100
  },
1986
- "cid": {
1987
- "type": "string",
1988
- "description": "Content identifier (CID). Not verified, just metadata.",
1989
- "example": "bafkreiabc123..."
1990
- },
1991
2101
  "description": {
1992
2102
  "type": "string",
1993
2103
  "description": "Description of the file",
@@ -2075,43 +2185,31 @@
2075
2185
  }
2076
2186
  ]
2077
2187
  },
2078
- "DownloadResponse": {
2079
- "type": "object",
2080
- "properties": {
2081
- "download_url": {
2082
- "type": "string",
2083
- "format": "uri",
2084
- "description": "Presigned S3 URL for downloading file content",
2085
- "example": "https://arke-blocks.s3.amazonaws.com/01JFILE123.../v1?X-Amz-..."
2086
- },
2087
- "expires_at": {
2088
- "type": "string",
2089
- "format": "date-time",
2090
- "description": "When the download URL expires (5 minutes)",
2091
- "example": "2025-12-26T12:00:00.000Z"
2092
- },
2093
- "filename": {
2094
- "type": "string",
2095
- "description": "Filename for download",
2096
- "example": "document.pdf"
2097
- },
2098
- "content_type": {
2099
- "type": "string",
2100
- "description": "MIME type of the file",
2101
- "example": "application/pdf"
2188
+ "UploadContentResponse": {
2189
+ "allOf": [
2190
+ {
2191
+ "$ref": "#/components/schemas/EntityResponse"
2102
2192
  },
2103
- "size": {
2104
- "type": "integer",
2105
- "description": "File size in bytes",
2106
- "example": 1048576
2193
+ {
2194
+ "type": "object",
2195
+ "properties": {
2196
+ "type": {
2197
+ "type": "string",
2198
+ "enum": [
2199
+ "file"
2200
+ ]
2201
+ },
2202
+ "prev_cid": {
2203
+ "type": "string",
2204
+ "minLength": 1,
2205
+ "description": "Previous version CID",
2206
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
2207
+ }
2208
+ },
2209
+ "required": [
2210
+ "prev_cid"
2211
+ ]
2107
2212
  }
2108
- },
2109
- "required": [
2110
- "download_url",
2111
- "expires_at",
2112
- "filename",
2113
- "content_type",
2114
- "size"
2115
2213
  ]
2116
2214
  },
2117
2215
  "UpdateFileResponse": {
@@ -2269,7 +2367,7 @@
2269
2367
  "key": {
2270
2368
  "type": "string",
2271
2369
  "minLength": 1,
2272
- "description": "New storage key. Must already exist in S3 (for regression to old version)."
2370
+ "description": "New storage key. Must already exist in R2 (for regression to old version)."
2273
2371
  },
2274
2372
  "filename": {
2275
2373
  "type": "string",
@@ -2286,10 +2384,6 @@
2286
2384
  "minimum": 0,
2287
2385
  "description": "New file size in bytes"
2288
2386
  },
2289
- "cid": {
2290
- "type": "string",
2291
- "description": "New content identifier"
2292
- },
2293
2387
  "description": {
2294
2388
  "type": "string",
2295
2389
  "description": "New description"
@@ -2302,26 +2396,20 @@
2302
2396
  "ReuploadFileResponse": {
2303
2397
  "allOf": [
2304
2398
  {
2305
- "$ref": "#/components/schemas/UpdateFileResponse"
2399
+ "$ref": "#/components/schemas/FileResponse"
2306
2400
  },
2307
2401
  {
2308
2402
  "type": "object",
2309
2403
  "properties": {
2310
- "upload_url": {
2311
- "type": "string",
2312
- "format": "uri",
2313
- "description": "Presigned S3 URL for uploading new file content"
2314
- },
2315
- "upload_expires_at": {
2404
+ "prev_cid": {
2316
2405
  "type": "string",
2317
- "format": "date-time",
2318
- "description": "When the upload URL expires (15 minutes)",
2319
- "example": "2025-12-26T12:00:00.000Z"
2406
+ "minLength": 1,
2407
+ "description": "Previous version CID",
2408
+ "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
2320
2409
  }
2321
2410
  },
2322
2411
  "required": [
2323
- "upload_url",
2324
- "upload_expires_at"
2412
+ "prev_cid"
2325
2413
  ]
2326
2414
  }
2327
2415
  ]
@@ -2343,7 +2431,7 @@
2343
2431
  "key": {
2344
2432
  "type": "string",
2345
2433
  "minLength": 1,
2346
- "description": "New storage key. Must NOT already exist in S3.",
2434
+ "description": "New storage key. Must NOT already exist in R2.",
2347
2435
  "example": "v2"
2348
2436
  },
2349
2437
  "content_type": {
@@ -2355,7 +2443,7 @@
2355
2443
  "size": {
2356
2444
  "type": "integer",
2357
2445
  "minimum": 0,
2358
- "description": "Size of the new file in bytes",
2446
+ "description": "Expected size of the new file in bytes (verified on upload)",
2359
2447
  "example": 2097152
2360
2448
  },
2361
2449
  "filename": {
@@ -2363,10 +2451,6 @@
2363
2451
  "minLength": 1,
2364
2452
  "description": "New filename (optional, keeps current if not provided)"
2365
2453
  },
2366
- "cid": {
2367
- "type": "string",
2368
- "description": "Content identifier for new file"
2369
- },
2370
2454
  "description": {
2371
2455
  "type": "string",
2372
2456
  "description": "New description"
@@ -2379,51 +2463,6 @@
2379
2463
  "size"
2380
2464
  ]
2381
2465
  },
2382
- "ConfirmUploadResponse": {
2383
- "allOf": [
2384
- {
2385
- "$ref": "#/components/schemas/FileResponse"
2386
- },
2387
- {
2388
- "type": "object",
2389
- "properties": {
2390
- "prev_cid": {
2391
- "type": "string",
2392
- "minLength": 1,
2393
- "description": "Previous version CID. Not present if upload was already confirmed.",
2394
- "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
2395
- },
2396
- "already_confirmed": {
2397
- "type": "boolean",
2398
- "description": "True if upload was already confirmed. Entity was not modified.",
2399
- "example": false
2400
- }
2401
- },
2402
- "required": [
2403
- "already_confirmed"
2404
- ]
2405
- }
2406
- ]
2407
- },
2408
- "ConfirmUploadRequest": {
2409
- "type": "object",
2410
- "properties": {
2411
- "expect_tip": {
2412
- "type": "string",
2413
- "minLength": 1,
2414
- "description": "Current tip CID for CAS validation. Request fails with 409 if this does not match.",
2415
- "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
2416
- },
2417
- "note": {
2418
- "type": "string",
2419
- "description": "Optional note describing this change",
2420
- "example": "Added Chapter 42: The Whiteness of the Whale"
2421
- }
2422
- },
2423
- "required": [
2424
- "expect_tip"
2425
- ]
2426
- },
2427
2466
  "CreateFolderResponse": {
2428
2467
  "type": "object",
2429
2468
  "properties": {
@@ -4354,99 +4393,64 @@
4354
4393
  "keys"
4355
4394
  ]
4356
4395
  },
4357
- "EventItem": {
4396
+ "Event": {
4358
4397
  "type": "object",
4359
4398
  "properties": {
4360
- "event_cid": {
4361
- "type": "string",
4362
- "minLength": 1,
4363
- "description": "CID of this event in the event chain",
4364
- "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
4365
- },
4366
- "type": {
4367
- "type": "string",
4368
- "enum": [
4369
- "create",
4370
- "update"
4371
- ],
4372
- "description": "Type of entity change event",
4373
- "example": "create"
4399
+ "id": {
4400
+ "type": "integer",
4401
+ "description": "Auto-increment event ID (use as cursor)",
4402
+ "example": 12346
4374
4403
  },
4375
4404
  "pi": {
4376
4405
  "type": "string",
4377
4406
  "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
4378
- "description": "Entity ID that was created or updated",
4407
+ "description": "Entity ID that changed",
4379
4408
  "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
4380
4409
  },
4381
- "ver": {
4382
- "type": "integer",
4383
- "minimum": 0,
4384
- "exclusiveMinimum": true,
4385
- "description": "Entity version number",
4386
- "example": 1
4387
- },
4388
- "tip_cid": {
4410
+ "cid": {
4389
4411
  "type": "string",
4390
4412
  "minLength": 1,
4391
- "description": "CID of the entity manifest at this version",
4413
+ "description": "New manifest CID",
4392
4414
  "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
4393
4415
  },
4394
4416
  "ts": {
4395
4417
  "type": "string",
4396
- "format": "date-time",
4397
- "description": "When the event was recorded",
4398
- "example": "2025-12-26T12:00:00.000Z"
4418
+ "description": "ISO timestamp of the event",
4419
+ "example": "2025-01-15T12:00:01Z"
4399
4420
  }
4400
4421
  },
4401
4422
  "required": [
4402
- "event_cid",
4403
- "type",
4423
+ "id",
4404
4424
  "pi",
4405
- "ver",
4406
- "tip_cid",
4425
+ "cid",
4407
4426
  "ts"
4408
4427
  ]
4409
4428
  },
4410
4429
  "EventsListResponse": {
4411
4430
  "type": "object",
4412
4431
  "properties": {
4413
- "items": {
4432
+ "events": {
4414
4433
  "type": "array",
4415
4434
  "items": {
4416
- "$ref": "#/components/schemas/EventItem"
4435
+ "$ref": "#/components/schemas/Event"
4417
4436
  },
4418
- "description": "Events in reverse chronological order"
4437
+ "description": "List of events"
4438
+ },
4439
+ "has_more": {
4440
+ "type": "boolean",
4441
+ "description": "Whether there are more events available",
4442
+ "example": true
4419
4443
  },
4420
- "total_events": {
4444
+ "cursor": {
4421
4445
  "type": "integer",
4422
- "minimum": 0,
4423
- "description": "Total events in the event chain",
4424
- "example": 1542
4425
- },
4426
- "total_pis": {
4427
- "type": "integer",
4428
- "minimum": 0,
4429
- "description": "Total unique entity IDs across all events",
4430
- "example": 987
4431
- },
4432
- "has_more": {
4433
- "type": "boolean",
4434
- "description": "Whether more events exist beyond this page"
4435
- },
4436
- "next_cursor": {
4437
- "type": "string",
4438
- "nullable": true,
4439
- "minLength": 1,
4440
- "description": "CID to use as \"cursor\" parameter for next page",
4441
- "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
4446
+ "description": "Cursor for the next page (pass as ?after= parameter)",
4447
+ "example": 12347
4442
4448
  }
4443
4449
  },
4444
4450
  "required": [
4445
- "items",
4446
- "total_events",
4447
- "total_pis",
4451
+ "events",
4448
4452
  "has_more",
4449
- "next_cursor"
4453
+ "cursor"
4450
4454
  ]
4451
4455
  }
4452
4456
  },
@@ -5983,18 +5987,326 @@
5983
5987
  "content": {
5984
5988
  "application/json": {
5985
5989
  "schema": {
5986
- "$ref": "#/components/schemas/CreateEntityRequest"
5990
+ "$ref": "#/components/schemas/CreateEntityRequest"
5991
+ }
5992
+ }
5993
+ }
5994
+ },
5995
+ "responses": {
5996
+ "201": {
5997
+ "description": "Entity created",
5998
+ "content": {
5999
+ "application/json": {
6000
+ "schema": {
6001
+ "$ref": "#/components/schemas/EntityCreatedResponse"
6002
+ }
6003
+ }
6004
+ }
6005
+ },
6006
+ "400": {
6007
+ "description": "Bad Request - Invalid input",
6008
+ "content": {
6009
+ "application/json": {
6010
+ "schema": {
6011
+ "$ref": "#/components/schemas/ValidationErrorResponse"
6012
+ },
6013
+ "example": {
6014
+ "error": "Validation failed",
6015
+ "details": {
6016
+ "issues": [
6017
+ {
6018
+ "path": [
6019
+ "properties",
6020
+ "label"
6021
+ ],
6022
+ "message": "Required"
6023
+ }
6024
+ ]
6025
+ }
6026
+ }
6027
+ }
6028
+ }
6029
+ },
6030
+ "401": {
6031
+ "description": "Unauthorized - Missing or invalid authentication",
6032
+ "content": {
6033
+ "application/json": {
6034
+ "schema": {
6035
+ "$ref": "#/components/schemas/ErrorResponse"
6036
+ },
6037
+ "example": {
6038
+ "error": "Unauthorized: Missing or invalid authentication token"
6039
+ }
6040
+ }
6041
+ }
6042
+ },
6043
+ "403": {
6044
+ "description": "Forbidden - Insufficient permissions",
6045
+ "content": {
6046
+ "application/json": {
6047
+ "schema": {
6048
+ "$ref": "#/components/schemas/ErrorResponse"
6049
+ },
6050
+ "example": {
6051
+ "error": "Forbidden: You do not have permission to perform this action"
6052
+ }
6053
+ }
6054
+ }
6055
+ },
6056
+ "409": {
6057
+ "description": "Conflict - CAS validation failed (entity was modified)",
6058
+ "content": {
6059
+ "application/json": {
6060
+ "schema": {
6061
+ "$ref": "#/components/schemas/CASErrorResponse"
6062
+ },
6063
+ "example": {
6064
+ "error": "Conflict: entity was modified",
6065
+ "details": {
6066
+ "expected": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy",
6067
+ "actual": "bafyreinewabc123456789defghijklmnopqrstuvwxyz"
6068
+ }
6069
+ }
6070
+ }
6071
+ }
6072
+ }
6073
+ }
6074
+ }
6075
+ },
6076
+ "/entities/{id}": {
6077
+ "get": {
6078
+ "tags": [
6079
+ "Entities"
6080
+ ],
6081
+ "summary": "Get entity by ID",
6082
+ "description": "Returns any entity by ID. Permission check uses parent collection if entity belongs to one.",
6083
+ "x-arke-action": "entity:view",
6084
+ "x-arke-auth": "optional",
6085
+ "parameters": [
6086
+ {
6087
+ "schema": {
6088
+ "type": "string",
6089
+ "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
6090
+ "description": "Entity ID (ULID format)",
6091
+ "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
6092
+ },
6093
+ "required": true,
6094
+ "description": "Entity ID (ULID)",
6095
+ "name": "id",
6096
+ "in": "path"
6097
+ }
6098
+ ],
6099
+ "responses": {
6100
+ "200": {
6101
+ "description": "Entity found",
6102
+ "content": {
6103
+ "application/json": {
6104
+ "schema": {
6105
+ "$ref": "#/components/schemas/EntityResponse"
6106
+ }
6107
+ }
6108
+ }
6109
+ },
6110
+ "403": {
6111
+ "description": "Forbidden - Insufficient permissions",
6112
+ "content": {
6113
+ "application/json": {
6114
+ "schema": {
6115
+ "$ref": "#/components/schemas/ErrorResponse"
6116
+ },
6117
+ "example": {
6118
+ "error": "Forbidden: You do not have permission to perform this action"
6119
+ }
6120
+ }
6121
+ }
6122
+ },
6123
+ "404": {
6124
+ "description": "Not Found - Resource does not exist",
6125
+ "content": {
6126
+ "application/json": {
6127
+ "schema": {
6128
+ "$ref": "#/components/schemas/ErrorResponse"
6129
+ },
6130
+ "example": {
6131
+ "error": "Entity not found"
6132
+ }
6133
+ }
6134
+ }
6135
+ }
6136
+ }
6137
+ },
6138
+ "put": {
6139
+ "tags": [
6140
+ "Entities"
6141
+ ],
6142
+ "summary": "Update entity",
6143
+ "description": "Updates any entity with merge semantics. Properties are deep merged, relationships use upsert semantics. Use properties_remove and relationships_remove for deletions. Note: entity:update on a collection requires collection:update permission.",
6144
+ "x-arke-action": "entity:update",
6145
+ "x-arke-auth": "required",
6146
+ "security": [
6147
+ {
6148
+ "bearerAuth": []
6149
+ }
6150
+ ],
6151
+ "parameters": [
6152
+ {
6153
+ "schema": {
6154
+ "type": "string",
6155
+ "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
6156
+ "description": "Entity ID (ULID format)",
6157
+ "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
6158
+ },
6159
+ "required": true,
6160
+ "description": "Entity ID (ULID)",
6161
+ "name": "id",
6162
+ "in": "path"
6163
+ }
6164
+ ],
6165
+ "requestBody": {
6166
+ "content": {
6167
+ "application/json": {
6168
+ "schema": {
6169
+ "$ref": "#/components/schemas/UpdateEntityRequest"
6170
+ }
6171
+ }
6172
+ }
6173
+ },
6174
+ "responses": {
6175
+ "200": {
6176
+ "description": "Entity updated",
6177
+ "content": {
6178
+ "application/json": {
6179
+ "schema": {
6180
+ "$ref": "#/components/schemas/EntityUpdatedResponse"
6181
+ }
6182
+ }
6183
+ }
6184
+ },
6185
+ "400": {
6186
+ "description": "Bad Request - Invalid input",
6187
+ "content": {
6188
+ "application/json": {
6189
+ "schema": {
6190
+ "$ref": "#/components/schemas/ValidationErrorResponse"
6191
+ },
6192
+ "example": {
6193
+ "error": "Validation failed",
6194
+ "details": {
6195
+ "issues": [
6196
+ {
6197
+ "path": [
6198
+ "properties",
6199
+ "label"
6200
+ ],
6201
+ "message": "Required"
6202
+ }
6203
+ ]
6204
+ }
6205
+ }
6206
+ }
6207
+ }
6208
+ },
6209
+ "401": {
6210
+ "description": "Unauthorized - Missing or invalid authentication",
6211
+ "content": {
6212
+ "application/json": {
6213
+ "schema": {
6214
+ "$ref": "#/components/schemas/ErrorResponse"
6215
+ },
6216
+ "example": {
6217
+ "error": "Unauthorized: Missing or invalid authentication token"
6218
+ }
6219
+ }
6220
+ }
6221
+ },
6222
+ "403": {
6223
+ "description": "Forbidden - Insufficient permissions",
6224
+ "content": {
6225
+ "application/json": {
6226
+ "schema": {
6227
+ "$ref": "#/components/schemas/ErrorResponse"
6228
+ },
6229
+ "example": {
6230
+ "error": "Forbidden: You do not have permission to perform this action"
6231
+ }
6232
+ }
6233
+ }
6234
+ },
6235
+ "404": {
6236
+ "description": "Not Found - Resource does not exist",
6237
+ "content": {
6238
+ "application/json": {
6239
+ "schema": {
6240
+ "$ref": "#/components/schemas/ErrorResponse"
6241
+ },
6242
+ "example": {
6243
+ "error": "Entity not found"
6244
+ }
6245
+ }
6246
+ }
6247
+ },
6248
+ "409": {
6249
+ "description": "Conflict - CAS validation failed (entity was modified)",
6250
+ "content": {
6251
+ "application/json": {
6252
+ "schema": {
6253
+ "$ref": "#/components/schemas/CASErrorResponse"
6254
+ },
6255
+ "example": {
6256
+ "error": "Conflict: entity was modified",
6257
+ "details": {
6258
+ "expected": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy",
6259
+ "actual": "bafyreinewabc123456789defghijklmnopqrstuvwxyz"
6260
+ }
6261
+ }
6262
+ }
6263
+ }
6264
+ }
6265
+ }
6266
+ },
6267
+ "delete": {
6268
+ "tags": [
6269
+ "Entities"
6270
+ ],
6271
+ "summary": "Delete entity",
6272
+ "description": "Soft-deletes an entity by creating a tombstone version. The entity can be restored later via POST /entities/:id/restore. Note: entity:delete on a collection requires collection:delete permission.",
6273
+ "x-arke-action": "entity:delete",
6274
+ "x-arke-auth": "required",
6275
+ "security": [
6276
+ {
6277
+ "bearerAuth": []
6278
+ }
6279
+ ],
6280
+ "parameters": [
6281
+ {
6282
+ "schema": {
6283
+ "type": "string",
6284
+ "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
6285
+ "description": "Entity ID (ULID format)",
6286
+ "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
6287
+ },
6288
+ "required": true,
6289
+ "description": "Entity ID (ULID)",
6290
+ "name": "id",
6291
+ "in": "path"
6292
+ }
6293
+ ],
6294
+ "requestBody": {
6295
+ "content": {
6296
+ "application/json": {
6297
+ "schema": {
6298
+ "$ref": "#/components/schemas/DeleteEntityRequest"
5987
6299
  }
5988
6300
  }
5989
6301
  }
5990
6302
  },
5991
6303
  "responses": {
5992
- "201": {
5993
- "description": "Entity created",
6304
+ "200": {
6305
+ "description": "Entity deleted",
5994
6306
  "content": {
5995
6307
  "application/json": {
5996
6308
  "schema": {
5997
- "$ref": "#/components/schemas/EntityCreatedResponse"
6309
+ "$ref": "#/components/schemas/EntityDeletedResponse"
5998
6310
  }
5999
6311
  }
6000
6312
  }
@@ -6049,95 +6361,47 @@
6049
6361
  }
6050
6362
  }
6051
6363
  },
6052
- "409": {
6053
- "description": "Conflict - CAS validation failed (entity was modified)",
6054
- "content": {
6055
- "application/json": {
6056
- "schema": {
6057
- "$ref": "#/components/schemas/CASErrorResponse"
6058
- },
6059
- "example": {
6060
- "error": "Conflict: entity was modified",
6061
- "details": {
6062
- "expected": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy",
6063
- "actual": "bafyreinewabc123456789defghijklmnopqrstuvwxyz"
6064
- }
6065
- }
6066
- }
6067
- }
6068
- }
6069
- }
6070
- }
6071
- },
6072
- "/entities/{id}": {
6073
- "get": {
6074
- "tags": [
6075
- "Entities"
6076
- ],
6077
- "summary": "Get entity by ID",
6078
- "description": "Returns any entity by ID. Permission check uses parent collection if entity belongs to one.",
6079
- "x-arke-action": "entity:view",
6080
- "x-arke-auth": "optional",
6081
- "parameters": [
6082
- {
6083
- "schema": {
6084
- "type": "string",
6085
- "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
6086
- "description": "Entity ID (ULID format)",
6087
- "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
6088
- },
6089
- "required": true,
6090
- "description": "Entity ID (ULID)",
6091
- "name": "id",
6092
- "in": "path"
6093
- }
6094
- ],
6095
- "responses": {
6096
- "200": {
6097
- "description": "Entity found",
6098
- "content": {
6099
- "application/json": {
6100
- "schema": {
6101
- "$ref": "#/components/schemas/EntityResponse"
6102
- }
6103
- }
6104
- }
6105
- },
6106
- "403": {
6107
- "description": "Forbidden - Insufficient permissions",
6364
+ "404": {
6365
+ "description": "Not Found - Resource does not exist",
6108
6366
  "content": {
6109
6367
  "application/json": {
6110
6368
  "schema": {
6111
6369
  "$ref": "#/components/schemas/ErrorResponse"
6112
6370
  },
6113
6371
  "example": {
6114
- "error": "Forbidden: You do not have permission to perform this action"
6372
+ "error": "Entity not found"
6115
6373
  }
6116
6374
  }
6117
6375
  }
6118
6376
  },
6119
- "404": {
6120
- "description": "Not Found - Resource does not exist",
6377
+ "409": {
6378
+ "description": "Conflict - CAS validation failed (entity was modified)",
6121
6379
  "content": {
6122
6380
  "application/json": {
6123
6381
  "schema": {
6124
- "$ref": "#/components/schemas/ErrorResponse"
6382
+ "$ref": "#/components/schemas/CASErrorResponse"
6125
6383
  },
6126
6384
  "example": {
6127
- "error": "Entity not found"
6385
+ "error": "Conflict: entity was modified",
6386
+ "details": {
6387
+ "expected": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy",
6388
+ "actual": "bafyreinewabc123456789defghijklmnopqrstuvwxyz"
6389
+ }
6128
6390
  }
6129
6391
  }
6130
6392
  }
6131
6393
  }
6132
6394
  }
6133
- },
6134
- "put": {
6395
+ }
6396
+ },
6397
+ "/entities/{id}/restore": {
6398
+ "post": {
6135
6399
  "tags": [
6136
6400
  "Entities"
6137
6401
  ],
6138
- "summary": "Update entity",
6139
- "description": "Updates any entity with merge semantics. Properties are deep merged, relationships use upsert semantics. Use properties_remove and relationships_remove for deletions. Note: entity:update on a collection requires collection:update permission.",
6140
- "x-arke-action": "entity:update",
6402
+ "summary": "Restore deleted entity",
6403
+ "description": "Restores a deleted entity by finding the last non-deleted version and creating a new version from it. Note: entity:restore on a collection requires collection:restore permission.",
6404
+ "x-arke-action": "entity:restore",
6141
6405
  "x-arke-auth": "required",
6142
6406
  "security": [
6143
6407
  {
@@ -6162,18 +6426,18 @@
6162
6426
  "content": {
6163
6427
  "application/json": {
6164
6428
  "schema": {
6165
- "$ref": "#/components/schemas/UpdateEntityRequest"
6429
+ "$ref": "#/components/schemas/RestoreEntityRequest"
6166
6430
  }
6167
6431
  }
6168
6432
  }
6169
6433
  },
6170
6434
  "responses": {
6171
6435
  "200": {
6172
- "description": "Entity updated",
6436
+ "description": "Entity restored",
6173
6437
  "content": {
6174
6438
  "application/json": {
6175
6439
  "schema": {
6176
- "$ref": "#/components/schemas/EntityUpdatedResponse"
6440
+ "$ref": "#/components/schemas/EntityRestoredResponse"
6177
6441
  }
6178
6442
  }
6179
6443
  }
@@ -6499,7 +6763,7 @@
6499
6763
  "Files"
6500
6764
  ],
6501
6765
  "summary": "Create file entity",
6502
- "description": "Creates a new file entity and returns a presigned upload URL.\n\n## Flow\n1. Call this endpoint with file metadata (key, filename, content_type, size)\n2. Receive entity data + presigned S3 upload URL (uploaded: false)\n3. PUT the file content to the upload URL\n4. Call POST /{id}/confirm-upload to verify and set uploaded: true\n\n## Key Best Practice\nUse the file's CID as the key for content-addressable storage.\nThe system does NOT verify the CID - it's just metadata.",
6766
+ "description": "Creates a new file entity.\n\n## Flow\n1. Call this endpoint with file metadata (key, filename, content_type, size)\n2. Receive entity data (uploaded: false)\n3. POST the file content to /{id}/content\n4. Entity will be updated with uploaded: true and verified CID\n\n## Key Best Practice\nUse a unique identifier as the key (e.g., version number, timestamp).\nThe actual CID is computed during upload.",
6503
6767
  "x-arke-action": "file:create",
6504
6768
  "x-arke-auth": "required",
6505
6769
  "security": [
@@ -6603,7 +6867,7 @@
6603
6867
  "Files"
6604
6868
  ],
6605
6869
  "summary": "Get file metadata",
6606
- "description": "Returns file entity metadata. Use /download to get the file content.",
6870
+ "description": "Returns file entity metadata. Use /{id}/content to download the file content.",
6607
6871
  "x-arke-action": "file:view",
6608
6872
  "x-arke-auth": "optional",
6609
6873
  "parameters": [
@@ -6664,7 +6928,7 @@
6664
6928
  "Files"
6665
6929
  ],
6666
6930
  "summary": "Update file metadata",
6667
- "description": "Updates file metadata without changing the file content.\n\n## Key Changes\nThe key can be changed, but ONLY to a key that already exists in S3.\nThis allows \"regressing\" to a previous file version.\n\nTo upload a new file, use POST /{id}/reupload instead.",
6931
+ "description": "Updates file metadata without changing the file content.\n\n## Key Changes\nThe key can be changed, but ONLY to a key that already exists in R2.\nThis allows \"regressing\" to a previous file version.\n\nTo upload a new file, use POST /{id}/reupload instead.",
6668
6932
  "x-arke-action": "file:update",
6669
6933
  "x-arke-auth": "required",
6670
6934
  "security": [
@@ -6789,77 +7053,14 @@
6789
7053
  }
6790
7054
  }
6791
7055
  },
6792
- "/files/{id}/download": {
6793
- "get": {
6794
- "tags": [
6795
- "Files"
6796
- ],
6797
- "summary": "Get download URL",
6798
- "description": "Returns a presigned URL for downloading the file content. URL expires in 5 minutes.",
6799
- "x-arke-action": "file:download",
6800
- "x-arke-auth": "optional",
6801
- "parameters": [
6802
- {
6803
- "schema": {
6804
- "type": "string",
6805
- "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
6806
- "description": "Entity ID (ULID format)",
6807
- "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
6808
- },
6809
- "required": true,
6810
- "description": "Entity ID (ULID)",
6811
- "name": "id",
6812
- "in": "path"
6813
- }
6814
- ],
6815
- "responses": {
6816
- "200": {
6817
- "description": "Download URL generated",
6818
- "content": {
6819
- "application/json": {
6820
- "schema": {
6821
- "$ref": "#/components/schemas/DownloadResponse"
6822
- }
6823
- }
6824
- }
6825
- },
6826
- "403": {
6827
- "description": "Forbidden - Insufficient permissions",
6828
- "content": {
6829
- "application/json": {
6830
- "schema": {
6831
- "$ref": "#/components/schemas/ErrorResponse"
6832
- },
6833
- "example": {
6834
- "error": "Forbidden: You do not have permission to perform this action"
6835
- }
6836
- }
6837
- }
6838
- },
6839
- "404": {
6840
- "description": "Not Found - Resource does not exist",
6841
- "content": {
6842
- "application/json": {
6843
- "schema": {
6844
- "$ref": "#/components/schemas/ErrorResponse"
6845
- },
6846
- "example": {
6847
- "error": "Entity not found"
6848
- }
6849
- }
6850
- }
6851
- }
6852
- }
6853
- }
6854
- },
6855
- "/files/{id}/reupload": {
7056
+ "/files/{id}/content": {
6856
7057
  "post": {
6857
7058
  "tags": [
6858
7059
  "Files"
6859
7060
  ],
6860
- "summary": "Upload new file version",
6861
- "description": "Uploads a new version of a file.\n\n## Flow\n1. Call this endpoint with new key and file metadata\n2. Receive updated entity + presigned upload URL (uploaded: false)\n3. PUT the new file content to the upload URL\n4. Call POST /{id}/confirm-upload to verify and set uploaded: true\n5. Old file versions remain accessible via manifest history\n\n## Key Requirement\nThe new key must NOT already exist in S3 (no overwrites).\nPrevious file versions are preserved.",
6862
- "x-arke-action": "file:reupload",
7061
+ "summary": "Upload file content",
7062
+ "description": "Uploads the binary content for a file entity.\n\n## Request\n- Content-Type: The MIME type of the file (must match entity's content_type)\n- Body: Binary file content (streaming supported)\n\n## Limits\n- Maximum file size: 500 MB\n\n## Behavior\n- Streams content directly to R2\n- Computes CID from file bytes\n- Updates entity with uploaded: true, verified size, and computed CID\n- Atomic operation - either fully succeeds or fails\n\n## Idempotency\nRe-uploading content for an already-uploaded file will fail with 409 Conflict.\nUse POST /{id}/reupload first to create a new version.",
7063
+ "x-arke-action": "file:upload",
6863
7064
  "x-arke-auth": "required",
6864
7065
  "security": [
6865
7066
  {
@@ -6880,22 +7081,13 @@
6880
7081
  "in": "path"
6881
7082
  }
6882
7083
  ],
6883
- "requestBody": {
6884
- "content": {
6885
- "application/json": {
6886
- "schema": {
6887
- "$ref": "#/components/schemas/ReuploadFileRequest"
6888
- }
6889
- }
6890
- }
6891
- },
6892
7084
  "responses": {
6893
7085
  "200": {
6894
- "description": "File version created",
7086
+ "description": "File content uploaded",
6895
7087
  "content": {
6896
7088
  "application/json": {
6897
7089
  "schema": {
6898
- "$ref": "#/components/schemas/ReuploadFileResponse"
7090
+ "$ref": "#/components/schemas/UploadContentResponse"
6899
7091
  }
6900
7092
  }
6901
7093
  }
@@ -6979,18 +7171,103 @@
6979
7171
  }
6980
7172
  }
6981
7173
  }
7174
+ },
7175
+ "413": {
7176
+ "description": "File too large (max 500 MB)",
7177
+ "content": {
7178
+ "application/json": {
7179
+ "schema": {
7180
+ "$ref": "#/components/schemas/ValidationErrorResponse"
7181
+ }
7182
+ }
7183
+ }
7184
+ },
7185
+ "500": {
7186
+ "description": "Internal Server Error",
7187
+ "content": {
7188
+ "application/json": {
7189
+ "schema": {
7190
+ "$ref": "#/components/schemas/ErrorResponse"
7191
+ },
7192
+ "example": {
7193
+ "error": "Internal server error"
7194
+ }
7195
+ }
7196
+ }
7197
+ }
7198
+ }
7199
+ },
7200
+ "get": {
7201
+ "tags": [
7202
+ "Files"
7203
+ ],
7204
+ "summary": "Download file content",
7205
+ "description": "Downloads the binary content of a file entity.\n\n## Response Headers\n- Content-Type: The MIME type of the file\n- Content-Length: File size in bytes\n- Content-Disposition: attachment; filename=\"original_filename\"\n\n## Streaming\nResponse is streamed directly from R2 storage.",
7206
+ "x-arke-action": "file:download",
7207
+ "x-arke-auth": "optional",
7208
+ "parameters": [
7209
+ {
7210
+ "schema": {
7211
+ "type": "string",
7212
+ "pattern": "^(?:II[0-9A-HJKMNP-TV-Z]{24}|[FC][0-9A-HJKMNP-TV-Z]{25}|[0-9A-HJKMNP-TV-Z]{26})$",
7213
+ "description": "Entity ID (ULID format)",
7214
+ "example": "01KDETYWYWM0MJVKM8DK3AEXPY"
7215
+ },
7216
+ "required": true,
7217
+ "description": "Entity ID (ULID)",
7218
+ "name": "id",
7219
+ "in": "path"
7220
+ }
7221
+ ],
7222
+ "responses": {
7223
+ "200": {
7224
+ "description": "File content",
7225
+ "content": {
7226
+ "application/octet-stream": {
7227
+ "schema": {
7228
+ "type": "string",
7229
+ "format": "binary"
7230
+ }
7231
+ }
7232
+ }
7233
+ },
7234
+ "403": {
7235
+ "description": "Forbidden - Insufficient permissions",
7236
+ "content": {
7237
+ "application/json": {
7238
+ "schema": {
7239
+ "$ref": "#/components/schemas/ErrorResponse"
7240
+ },
7241
+ "example": {
7242
+ "error": "Forbidden: You do not have permission to perform this action"
7243
+ }
7244
+ }
7245
+ }
7246
+ },
7247
+ "404": {
7248
+ "description": "Not Found - Resource does not exist",
7249
+ "content": {
7250
+ "application/json": {
7251
+ "schema": {
7252
+ "$ref": "#/components/schemas/ErrorResponse"
7253
+ },
7254
+ "example": {
7255
+ "error": "Entity not found"
7256
+ }
7257
+ }
7258
+ }
6982
7259
  }
6983
7260
  }
6984
7261
  }
6985
7262
  },
6986
- "/files/{id}/confirm-upload": {
7263
+ "/files/{id}/reupload": {
6987
7264
  "post": {
6988
7265
  "tags": [
6989
7266
  "Files"
6990
7267
  ],
6991
- "summary": "Confirm upload completed",
6992
- "description": "Confirms that file content has been uploaded to S3.\n\n## Flow\n1. Create file entity (POST /files) - sets uploaded: false\n2. PUT file content to the presigned upload URL\n3. Call this endpoint to confirm - verifies file exists in S3, sets uploaded: true\n\n## Verification\nThe server verifies the file exists in S3 before setting uploaded: true.\nIf the file doesn't exist, returns 400 error.\n\n## Idempotency\nIf already uploaded: true, returns success without modification.",
6993
- "x-arke-action": "file:update",
7268
+ "summary": "Prepare for new file version",
7269
+ "description": "Prepares the entity for uploading a new file version.\n\n## Flow\n1. Call this endpoint with new key and file metadata\n2. Receive updated entity (uploaded: false)\n3. POST the new file content to /{id}/content\n4. Entity will be updated with uploaded: true and verified CID\n\n## Key Requirement\nThe new key must NOT already exist in R2 (no overwrites).\nPrevious file versions remain accessible via manifest history.",
7270
+ "x-arke-action": "file:reupload",
6994
7271
  "x-arke-auth": "required",
6995
7272
  "security": [
6996
7273
  {
@@ -7015,18 +7292,18 @@
7015
7292
  "content": {
7016
7293
  "application/json": {
7017
7294
  "schema": {
7018
- "$ref": "#/components/schemas/ConfirmUploadRequest"
7295
+ "$ref": "#/components/schemas/ReuploadFileRequest"
7019
7296
  }
7020
7297
  }
7021
7298
  }
7022
7299
  },
7023
7300
  "responses": {
7024
7301
  "200": {
7025
- "description": "Upload confirmed",
7302
+ "description": "Ready for new file version upload",
7026
7303
  "content": {
7027
7304
  "application/json": {
7028
7305
  "schema": {
7029
- "$ref": "#/components/schemas/ConfirmUploadResponse"
7306
+ "$ref": "#/components/schemas/ReuploadFileResponse"
7030
7307
  }
7031
7308
  }
7032
7309
  }
@@ -8970,40 +9247,53 @@
8970
9247
  "tags": [
8971
9248
  "Events"
8972
9249
  ],
8973
- "summary": "List events",
8974
- "description": "Returns entity change events in reverse chronological order (newest first).\n\nEach event represents a create or update operation on an entity. Use cursor-based pagination to walk through the event history.\n\n**Use cases:**\n- Syncing entity changes to external systems\n- Building search indexes\n- Change tracking and audit logs\n\n**Note:** This endpoint is public. Access control is enforced at the entity level - if you don't have permission to view an entity, you won't be able to fetch its manifest even if you see an event for it.",
9250
+ "summary": "List entity change events",
9251
+ "description": "Returns a cursor-based list of entity change events for client synchronization.\n\n**Usage:**\n- Start with `?after=0` to get all events\n- Use the returned `cursor` as `?after=` for the next page\n- Poll periodically (e.g., every 10s) to stay in sync\n\n**Event data:**\n- `id`: Auto-increment ID (use as cursor)\n- `pi`: Entity ID that changed\n- `cid`: New manifest CID\n- `ts`: ISO timestamp\n\nEvents are ephemeral (30-day rolling window) - for full sync, use snapshots.",
8975
9252
  "x-arke-action": "events:list",
8976
9253
  "x-arke-auth": "none",
8977
9254
  "parameters": [
9255
+ {
9256
+ "schema": {
9257
+ "type": "integer",
9258
+ "nullable": true,
9259
+ "minimum": 0,
9260
+ "example": 12345
9261
+ },
9262
+ "required": false,
9263
+ "description": "Return events with id > after (cursor for pagination)",
9264
+ "name": "after",
9265
+ "in": "query"
9266
+ },
8978
9267
  {
8979
9268
  "schema": {
8980
9269
  "type": "integer",
8981
9270
  "minimum": 1,
8982
- "maximum": 100,
8983
- "default": 50,
8984
- "example": 50
9271
+ "maximum": 1000,
9272
+ "example": 100
8985
9273
  },
8986
9274
  "required": false,
8987
- "description": "Maximum events to return (1-100, default 50)",
9275
+ "description": "Maximum number of events to return (default: 100, max: 1000)",
8988
9276
  "name": "limit",
8989
9277
  "in": "query"
8990
9278
  },
8991
9279
  {
8992
9280
  "schema": {
8993
9281
  "type": "string",
8994
- "minLength": 1,
8995
- "description": "IPFS Content Identifier (CID)",
8996
- "example": "bafyreibug443cnd4endcwinwttw3c3dzmcl2ikht64xzn5qg56bix3usfy"
9282
+ "enum": [
9283
+ "main",
9284
+ "test"
9285
+ ],
9286
+ "example": "main"
8997
9287
  },
8998
9288
  "required": false,
8999
- "description": "Event CID to continue from (for pagination)",
9000
- "name": "cursor",
9289
+ "description": "Network to query (default: main)",
9290
+ "name": "network",
9001
9291
  "in": "query"
9002
9292
  }
9003
9293
  ],
9004
9294
  "responses": {
9005
9295
  "200": {
9006
- "description": "Event list",
9296
+ "description": "Events list",
9007
9297
  "content": {
9008
9298
  "application/json": {
9009
9299
  "schema": {