Update Project
Update a project’s name or description. This operation does not affect the project’s files or storage.
Endpoint
PUT /api/projects/{project_id}Authentication
Required: API key
Authorization: Bearer YOUR_API_KEYRequest
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | UUID | Yes | Unique project identifier |
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes |
Content-Type | application/json | Yes |
Request Body
{
"name": "AI Articles 2025 - Updated",
"description": "Updated description for AI articles collection"
}Fields
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
name | string | No | 1-255 chars, unique | New project name |
description | string|null | No | Any length | New project description |
Update Behavior:
- Both fields are optional - provide only fields you want to update
nullfor description will clear the description- Name must still be unique if provided
- At least one field must be provided
Response
Success Response (200 OK)
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "AI Articles 2025 - Updated",
"description": "Updated description for AI articles collection",
"bucket_name": "markdown-api-user123-a1b2c3d4",
"is_default": false,
"is_active": true,
"file_count": 42,
"total_size_bytes": 2097152,
"created_date": "2025-01-09T10:00:00Z",
"updated_date": "2025-01-09T16:00:00Z"
}Error Responses
| Status | Error | Description | Solution |
|---|---|---|---|
| 400 | Bad Request | No fields provided or invalid JSON | Provide at least one field to update |
| 401 | Unauthorized | Missing or invalid authentication | Verify Bearer token or API key |
| 403 | Forbidden | Project belongs to another user | Verify project_id belongs to your account |
| 404 | Not Found | Project doesn’t exist | Check project_id is correct |
| 409 | Conflict | New name already exists | Choose different name |
| 422 | Unprocessable Entity | Validation error | Check field constraints |
| 429 | Too Many Requests | Rate limit exceeded | Wait and retry |
| 500 | Internal Server Error | Server error | Contact support if persists |
Examples
cURL
# Update name only
curl -X PUT "https://markdownapi.io/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "AI Articles 2025 - Updated"}'
# Update description only
curl -X PUT "https://markdownapi.io/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description": "New description"}'
# Update both
curl -X PUT "https://markdownapi.io/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "AI Articles 2025 - Updated",
"description": "New description"
}'
# Clear description
curl -X PUT "https://markdownapi.io/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"description": null}'Python (httpx)
import httpx
import os
from uuid import UUID
async def update_project(
project_id: UUID,
name: str | None = None,
description: str | None = None
):
"""Update project with optional name and description."""
if name is None and description is None:
raise ValueError("Must provide at least one field to update")
api_key = os.getenv("MARKDOWN_API_KEY")
update_data = {}
if name is not None:
update_data["name"] = name
if description is not None:
update_data["description"] = description
async with httpx.AsyncClient() as client:
try:
response = await client.put(
f"https://markdownapi.io/api/projects/{project_id}",
headers={"Authorization": f"Bearer {api_key}"},
json=update_data,
timeout=10.0
)
response.raise_for_status()
project = response.json()
print(f"✓ Project updated: {project['name']}")
print(f" Updated: {project['updated_date']}")
return project
except httpx.HTTPStatusError as e:
if e.response.status_code == 409:
print(f"✗ Name already exists")
elif e.response.status_code == 404:
print(f"✗ Project not found")
else:
print(f"✗ HTTP error: {e.response.status_code}")
raise
# Usage
# project = await update_project(
# project_id=UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
# name="New Name",
# description="New description"
# )TypeScript
interface UpdateProjectRequest {
name?: string;
description?: string | null;
}
async function updateProject(
projectId: string,
updates: UpdateProjectRequest
): Promise<ProjectResponse> {
if (!updates.name && updates.description === undefined) {
throw new Error('Must provide at least one field to update');
}
const apiKey = process.env.MARKDOWN_API_KEY;
try {
const response = await fetch(
`https://markdownapi.io/api/projects/${projectId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${apiKey!}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(updates),
}
);
if (!response.ok) {
if (response.status === 409) {
throw new Error('Name already exists');
} else if (response.status === 404) {
throw new Error('Project not found');
}
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const project: ProjectResponse = await response.json();
console.log(`✓ Project updated: ${project.name}`);
console.log(` Updated: ${project.updated_date}`);
return project;
} catch (error) {
console.error('✗ Failed to update project:', error);
throw error;
}
}
// Usage
// await updateProject('a1b2c3d4-e5f6-7890-abcd-ef1234567890', {
// name: 'New Name',
// description: 'New description'
// });Common Use Cases
1. Rename Project
async def rename_project(project_id: UUID, new_name: str):
"""Rename project without changing description."""
return await update_project(project_id, name=new_name)2. Update Description Only
async def update_project_description(project_id: UUID, description: str):
"""Update description without changing name."""
return await update_project(project_id, description=description)3. Clear Description
async def clear_project_description(project_id: UUID):
"""Remove project description."""
return await update_project(project_id, description=None)4. Add Timestamp to Name
from datetime import datetime
async def archive_project(project_id: UUID):
"""Add archive timestamp to project name."""
project = await get_project(project_id)
timestamp = datetime.utcnow().strftime("%Y-%m-%d")
new_name = f"[ARCHIVED {timestamp}] {project['name']}"
return await update_project(project_id, name=new_name)Best Practices
- Partial updates - Only send fields you want to change
- Verify uniqueness - Check name doesn’t exist before updating
- Handle conflicts - Gracefully handle 409 errors for duplicate names
- Preserve data - Use null explicitly to clear description, not to preserve it
See Also
- Get Project - View project details
- Delete Project - Remove project
- Projects Overview - Learn about projects
Last updated on