# Save Endpoint

Save content to Context Link's memory. Saved content is indexed into vector embeddings and can be retrieved later via the [Context endpoint](/docs/context-endpoint) or by namespace.

## Quick reference

| Property | Value |
|----------|-------|
| **Endpoint** | `POST /api/v1/context/save` |
| **Authentication** | API key via `Authorization` header |
| **Rate limit** | 5 requests per 10 seconds |
| **Content-Type** | `application/json` |
| **Response format** | JSON |

### Parameters

| Parameter | Type | Location | Required | Description |
|-----------|------|----------|----------|-------------|
| `namespace` | string | Query string | Yes | A name for the saved content. Used for retrieval and versioning. Case-insensitive, spaces become dashes. |

### Request body

The body should be JSON. Accepted formats:

- **JSON array of strings** (recommended) — each string becomes a chunk of 800-3200 characters
- **JSON string** — a single block of content
- **JSON object** — converted to markdown automatically

### Status codes

| Code | Description |
|------|-------------|
| `201` | Content saved successfully |
| `400` | Namespace parameter is missing |
| `401` | API key is missing or subscription required |
| `404` | API key is invalid |
| `422` | Request body is empty |
| `429` | Rate limit exceeded |

## Examples

### Basic usage

```bash
curl -X POST "https://context-link.ai/api/v1/context/save?namespace=meeting-notes" \
     -H "Authorization: your-api-key-here" \
     -H "Content-Type: application/json" \
     -d '["Meeting notes from Feb 15: discussed roadmap priorities and Q2 goals..."]'
```

**Response (201 Created):**

```json
{
    "message": "Saved",
    "namespace": "meeting-notes"
}
```

### Python example

```python
import requests

api_key = "your-api-key-here"

# Save content under a namespace
response = requests.post(
    "https://context-link.ai/api/v1/context/save",
    params={"namespace": "project-notes"},
    headers={
        "Authorization": api_key,
        "Content-Type": "application/json"
    },
    json=["First chunk of content...", "Second chunk of content..."]
)

data = response.json()
print(data["message"])    # "Saved"
print(data["namespace"])  # "project-notes"
```

### JavaScript example

```javascript
const apiKey = 'your-api-key-here';

fetch('https://context-link.ai/api/v1/context/save?namespace=project-notes', {
    method: 'POST',
    headers: {
        'Authorization': apiKey,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(['First chunk of content...', 'Second chunk of content...'])
})
.then(response => response.json())
.then(data => {
    console.log(data.message);    // "Saved"
    console.log(data.namespace);  // "project-notes"
});
```

## Namespaces and versioning

- Namespaces are **case-insensitive** and normalized (spaces become dashes).
- Saving to the same namespace creates a **new version**. The old content is kept, but retrieving by namespace always returns the latest version.
- You can use namespaces to organize memories by topic, e.g. `meeting-notes`, `project-roadmap`, `daily-standup`.

## Retrieving saved content

Saved content is automatically available through the [Context endpoint](/docs/context-endpoint). If you saved with a namespace, querying that exact namespace returns the content directly without a vector search.

```bash
# Retrieve by namespace
curl -X GET "https://context-link.ai/api/v1/context?query=meeting-notes" \
     -H "Authorization: your-api-key-here"
```

Content saved without a namespace is still searchable via semantic search — just query with related terms.

## Error responses

```json
// 400 Bad Request - Missing namespace
{
    "error": "A namespace is required"
}

// 422 Unprocessable Entity - Empty body
{
    "error": "No content provided"
}

// 401 Unauthorized - Missing API key
{
    "message": "API key required"
}

// 401 Unauthorized - Subscription required
{
    "message": "You need to be subscribed to access that page"
}

// 404 Not Found - Invalid API key
{
    "message": "Not found"
}
```
