# API Reference ## Base URL ``` https://api.slices.network/xrpc/ ``` For local development: ``` http://localhost:3000/xrpc/ ``` ## Authentication Write operations require OAuth 2.0 authentication with a Bearer token: ``` Authorization: Bearer YOUR_ACCESS_TOKEN ``` Read operations are public by default. ## Collection Endpoints For each collection in your slice (e.g., `com.recordcollector.album`), the following endpoints are automatically generated: # **{collection}.getRecords** > List records with filtering, sorting, and pagination. **Method:** `POST` **Endpoint:** `/xrpc/{collection}.getRecords` **Example:** `/xrpc/com.recordcollector.album.getRecords` **Request Body:** ```json { "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "limit": 20, "cursor": "optional-pagination-cursor", "where": { "genre": { "contains": "grunge" }, "condition": { "in": ["Mint", "Near Mint"] } }, "sortBy": [ { "field": "releaseDate", "direction": "desc" } ] } ``` **Parameters:** - `slice` (string, required): The slice URI to query - `limit` (number, optional): Maximum records to return (default: 50, max: 100) - `cursor` (string, optional): Pagination cursor from previous response - `where` (object, optional): Filter conditions. Field filters support operators: `eq`, `contains`, `in`. Special field `json` searches across all fields - `sortBy` (array, optional): Sort specification. Each item has `field` and `direction` ("asc" or "desc") **Response:** ```json { "records": [ { "uri": "at://did:plc:user123/com.recordcollector.album/3l2w4x5y6z", "cid": "bafyreigbtj4x7ip5legnfznufuopl4sg4knzc2cof6duas4b3q2fy6swua", "did": "did:plc:user123", "collection": "com.recordcollector.album", "value": { "$type": "com.recordcollector.album", "title": "Nevermind", "artist": "Nirvana", "releaseDate": "1991-09-24T00:00:00.000Z", "genre": ["grunge", "alternative rock"], "condition": "Near Mint", "notes": "Original pressing, includes poster" }, "indexedAt": "2024-03-15T10:30:15.123Z" } ], "cursor": "next-page-cursor-xyz789" } ``` # **{collection}.getRecord** > Get a single record by URI. **Method:** `GET` **Endpoint:** `/xrpc/{collection}.getRecord` **Example:** `/xrpc/com.recordcollector.album.getRecord` **Query Parameters:** - `slice` (string, required): The slice URI - `uri` (string, required): The AT Protocol URI of the record **Example Request:** ``` GET /xrpc/com.recordcollector.album.getRecord?slice=at://did:plc:abc123/network.slices.slice/xyz789&uri=at://did:plc:user123/com.recordcollector.album/3l2w4x5y6z ``` **Response:** ```json { "uri": "at://did:plc:user123/com.recordcollector.album/3l2w4x5y6z", "cid": "bafyreigbtj4x7ip5legnfznufuopl4sg4knzc2cof6duas4b3q2fy6swua", "did": "did:plc:user123", "collection": "com.recordcollector.album", "value": { "$type": "com.recordcollector.album", "title": "Nevermind", "artist": "Nirvana", "releaseDate": "1991-09-24T00:00:00.000Z", "genre": ["grunge", "alternative rock"], "condition": "Near Mint", "notes": "Original pressing, includes poster" }, "indexedAt": "2024-03-15T10:30:15.123Z" } ``` # **{collection}.countRecords** > Count records matching filter criteria. **Method:** `POST` **Endpoint:** `/xrpc/{collection}.countRecords` **Example:** `/xrpc/com.recordcollector.album.countRecords` **Request Body:** ```json { "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "where": { "condition": { "in": ["Mint", "Near Mint"] }, "genre": { "contains": "grunge" } } } ``` **Response:** ```json { "success": true, "count": 42, "message": "Count retrieved successfully" } ``` # **{collection}.createRecord** > Create a new record. **Method:** `POST` **Endpoint:** `/xrpc/{collection}.createRecord` **Example:** `/xrpc/com.recordcollector.album.createRecord` **Authentication:** Required **Request Body:** ```json { "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "rkey": "optional-custom-key", "record": { "$type": "com.recordcollector.album", "title": "In Utero", "artist": "Nirvana", "releaseDate": "1993-09-21T00:00:00.000Z", "genre": ["grunge", "alternative rock"], "condition": "Very Good Plus", "notes": "Some light wear on sleeve" } } ``` **Parameters:** - `slice` (string, required): The slice URI - `rkey` (string, optional): Custom record key (auto-generated if omitted) - `record` (object, required): The record data matching your lexicon schema **Response:** ```json { "uri": "at://did:plc:user123/com.recordcollector.album/3abc456def", "cid": "bafyreihj7x5legnfznufuopl4sg4knzc2cof6duas4b3q2fy6swua" } ``` # **{collection}.updateRecord** > Update an existing record. **Method:** `POST` **Endpoint:** `/xrpc/{collection}.updateRecord` **Example:** `/xrpc/com.recordcollector.album.updateRecord` **Authentication:** Required **Request Body:** ```json { "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "rkey": "3abc456def", "record": { "$type": "com.recordcollector.album", "title": "In Utero", "artist": "Nirvana", "releaseDate": "1993-09-21T00:00:00.000Z", "genre": ["grunge", "alternative rock", "noise rock"], "condition": "Very Good", "notes": "Updated: slight ring wear visible, plays perfectly" } } ``` **Parameters:** - `slice` (string, required): The slice URI - `rkey` (string, required): The record key to update - `record` (object, required): The complete updated record data **Response:** ```json { "uri": "at://did:plc:user123/com.recordcollector.album/3abc456def", "cid": "bafyreiabc123legnfznufuopl4sg4knzc2cof6duas4b3q2fy6swua" } ``` # **{collection}.deleteRecord** > Delete a record. **Method:** `POST` **Endpoint:** `/xrpc/{collection}.deleteRecord` **Example:** `/xrpc/com.recordcollector.album.deleteRecord` **Authentication:** Required **Request Body:** ```json { "rkey": "3abc456def" } ``` **Response:** ```json {} ``` ## Filtering The `where` parameter supports powerful filtering: ### Filter Operators - **`eq`**: Exact match ```json { "condition": { "eq": "Mint" } } ``` - **`contains`**: Partial text match (case-insensitive) ```json { "artist": { "contains": "pearl jam" } } ``` - **`in`**: Match any value in array ```json { "condition": { "in": ["Mint", "Near Mint", "Very Good Plus"] } } ``` ### Special Fields - **`json`**: Search across all fields ```json { "json": { "contains": "nirvana" } } ``` - **System fields**: Filter by record metadata ```json { "did": { "eq": "did:plc:user123" }, "collection": { "eq": "com.recordcollector.album" }, "indexedAt": { "contains": "2024-03" } } ``` ### Complex Filtering Examples **Multiple conditions (AND logic):** ```json { "where": { "genre": { "contains": "grunge" }, "condition": { "in": ["Mint", "Near Mint"] }, "releaseDate": { "contains": "1991" } } } ``` **Array field filtering:** ```json { "where": { "genre": { "contains": "alternative" } } } ``` ## Sorting Sort results using the `sortBy` parameter: ```json { "sortBy": [ { "field": "releaseDate", "direction": "desc" }, { "field": "artist", "direction": "asc" } ] } ``` **Common sort patterns:** - Newest releases first: `[{ "field": "releaseDate", "direction": "desc" }]` - Alphabetical by artist: `[{ "field": "artist", "direction": "asc" }]` - By condition (best first): `[{ "field": "condition", "direction": "asc" }]` - Recently indexed: `[{ "field": "indexedAt", "direction": "desc" }]` ## Pagination Use cursor-based pagination for large result sets: ```javascript // First request const page1 = await fetch('/xrpc/com.recordcollector.album.getRecords', { method: 'POST', body: JSON.stringify({ slice: 'at://your-slice-uri', limit: 20 }) }); // Next page using cursor const page2 = await fetch('/xrpc/com.recordcollector.album.getRecords', { method: 'POST', body: JSON.stringify({ slice: 'at://your-slice-uri', limit: 20, cursor: page1.cursor }) }); ``` ## Error Responses All endpoints return consistent error format: ```json { "error": "InvalidRequest", "message": "Missing required parameter: slice" } ``` **Common HTTP Status Codes:** - `200`: Success - `400`: Bad request (invalid parameters) - `401`: Unauthorized (missing/invalid auth token) - `403`: Forbidden (insufficient permissions) - `404`: Not found (record/collection doesn't exist) - `500`: Internal server error ## OpenAPI Specification Get the OpenAPI spec for your slice: **Method:** `GET` **Endpoint:** `/xrpc/network.slices.slice.openapi` **Query Parameters:** - `slice` (string, required): The slice URI **Response:** OpenAPI 3.0 specification with all available endpoints ## Example: Record Collector Application Here's a complete example using the record collector lexicon: ### Lexicon Definition ```json { "lexicon": 1, "id": "com.recordcollector.album", "defs": { "main": { "type": "record", "record": { "type": "object", "required": ["title", "artist", "releaseDate"], "properties": { "title": { "type": "string", "description": "Album title" }, "artist": { "type": "string", "description": "Artist or band name" }, "releaseDate": { "type": "string", "format": "datetime", "description": "Original release date" }, "genre": { "type": "array", "items": { "type": "string" }, "description": "Music genres" }, "condition": { "type": "string", "description": "Vinyl condition (Mint, Near Mint, etc.)" }, "notes": { "type": "string", "description": "Collector notes" } } } } } } ``` ### List Albums by Genre ```bash curl -X POST "https://api.slices.network/xrpc/com.recordcollector.album.getRecords" \ -H "Content-Type: application/json" \ -d '{ "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "where": { "genre": { "contains": "grunge" } }, "sortBy": [{ "field": "releaseDate", "direction": "desc" }], "limit": 10 }' ``` ### Add New Album to Collection ```bash curl -X POST "https://api.slices.network/xrpc/com.recordcollector.album.createRecord" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "record": { "$type": "com.recordcollector.album", "title": "Superunknown", "artist": "Soundgarden", "releaseDate": "1994-03-08T00:00:00.000Z", "genre": ["grunge", "alternative metal"], "condition": "Near Mint", "notes": "Limited edition orange vinyl" } }' ``` ### Search Collection by Condition ```bash curl -X POST "https://api.slices.network/xrpc/com.recordcollector.album.getRecords" \ -H "Content-Type: application/json" \ -d '{ "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "where": { "condition": { "in": ["Mint", "Near Mint"] }, "releaseDate": { "contains": "199" } }, "sortBy": [{ "field": "artist", "direction": "asc" }] }' ``` ### Count Albums in Collection ```bash curl -X POST "https://api.slices.network/xrpc/com.recordcollector.album.countRecords" \ -H "Content-Type: application/json" \ -d '{ "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "where": { "condition": { "eq": "Mint" } } }' ``` ### Update Album Condition ```bash curl -X POST "https://api.slices.network/xrpc/com.recordcollector.album.updateRecord" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "slice": "at://did:plc:abc123/network.slices.slice/xyz789", "rkey": "3abc456def", "record": { "$type": "com.recordcollector.album", "title": "Ten", "artist": "Pearl Jam", "releaseDate": "1991-08-27T00:00:00.000Z", "genre": ["grunge", "alternative rock"], "condition": "Very Good", "notes": "Updated after closer inspection - slight scuffs on Side B" } }' ``` ## Next Steps - [SDK Usage](./sdk-usage.md) - Using generated TypeScript clients - [Getting Started](./getting-started.md) - Build your first application - [Concepts](./concepts.md) - Understand the architecture