--- title: "DevPlace REST: Projects, Gists and News" description: "Project, gist and news endpoints: browsing and detail reads, create/edit/delete, private and read-only flags, zip export and fork jobs with their polling endpoints, and the news listing and article reads." language: null framework: null category: api_design tags: - devplace - api - http-api - projects - gists - news - crud - rest - async-jobs - export keywords: - devplace POST /projects/create endpoint - devplace project zip export job polling - devplace project fork endpoint - devplace gists create edit delete api - devplace news listing article json last_updated: 2026-08-12 difficulty: intermediate version: "DevPlace (devplace.net), documented 2026-08" related: - README.md - authentication.md - conventions_and_errors.md search_priority: normal status: published --- # DevPlace REST: Projects, Gists and News List projects. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `tab` | query | enum | no | Sort selector. Allowed: recent, popular, released. | | `search` | query | string | no | Search project title, description, and author username. | | `project_type` | query | enum | no | Filter by type. Allowed: game, game_asset, software, mobile_app, website. | | `before` | query | string | no | Pagination cursor. | **Sample response** ```json { "projects": [ { "uid": "UID", "slug": "slug", "user_uid": "UID", "title": "Title", "description": "text", "project_type": "string", "status": "published", "platforms": null, "stars": 0, "is_private": false, "read_only": false, "release_date": "string", "demo_date": "string", "created_at": "2026-01-01T00:00:00+00:00", "updated_at": "2026-01-01T00:00:00+00:00", "author_name": "string", "my_vote": 0, "recent_comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ] } ], "current_tab": "string", "search": "string", "project_type": "string", "total_count": 0, "next_cursor": "2026-01-01T00:00:00+00:00", "total_members": 0, "top_authors": [ { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" } ] } ``` ## `GET /projects/{project_slug}` - View a project Render a project with comments. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project. | **Sample response** ```json { "maturity": "string", "project": { "uid": "UID", "slug": "slug", "user_uid": "UID", "title": "Title", "description": "text", "project_type": "string", "status": "published", "platforms": null, "stars": 0, "is_private": false, "read_only": false, "release_date": "string", "demo_date": "string", "created_at": "2026-01-01T00:00:00+00:00", "updated_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "is_owner": false, "star_count": 0, "my_vote": 0, "time_ago": "2 hours ago", "comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] }, "bookmarked": false, "platforms": null, "is_private": false, "read_only": false, "viewer_can_containers": false, "viewer_can_workspace": false, "workspace_editor_url": "/path", "workspace_editor_mode": "string", "workspace_editor_width": 0, "workspace_editor_height": 0, "forked_from": {}, "fork_count": 0, "file_count": 0, "devlog_posts": [ { "post": { "uid": "UID", "slug": "slug", "user_uid": "UID", "title": "Title", "content": "text", "topic": "random", "stars": 0, "image": "string", "project_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00", "updated_at": "2026-01-01T00:00:00+00:00" }, "maturity": "string", "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "my_vote": 0, "comment_count": 0, "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "recent_comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ], "reactions": { "counts": {}, "mine": [] }, "bookmarked": false, "poll": { "uid": "UID", "question": "string", "options": [ { "uid": "UID", "label": "string", "count": 0, "votes": 0, "pct": 0 } ], "total": 0, "my_choice": "string", "voted": "string" }, "project_link": { "uid": "UID", "name": "string", "slug": "slug", "url": "/path" } } ], "devlog_next_cursor": "2026-01-01T00:00:00+00:00" } ``` ## `POST /projects/create` - Create a project Publish a project. Redirects to the new project. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `title` | form | string | yes | Title, 1-200 characters. | | `description` | form | textarea | yes | Description, 1-5000 characters. | | `project_type` | form | enum | no | Project type. Allowed: game, game_asset, software, mobile_app, website. | | `status` | form | string | no | Free-form status label. | | `platforms` | form | string | no | Comma-separated platforms. | | `release_date` | form | string | no | Optional release date in DD/MM/YYYY format. | | `demo_date` | form | string | no | Optional demo date in DD/MM/YYYY format. | **Sample response** ```json { "ok": true, "redirect": "/projects/PROJECT_SLUG", "data": { "uid": "PROJECT_UID", "slug": "PROJECT_SLUG", "url": "/projects/PROJECT_SLUG" } } ``` ## `POST /projects/edit/{project_slug}` - Edit a project Update an owned project. Redirects to the project. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Project slug or uid. | | `title` | form | string | yes | Title, 1-200 characters. | | `description` | form | textarea | yes | Description, 1-5000 characters. | | `project_type` | form | enum | no | Project type. Allowed: game, game_asset, software, mobile_app, website. | | `status` | form | string | no | Free-form status label. | | `platforms` | form | string | no | Comma-separated platforms. | | `release_date` | form | string | no | Optional release date in DD/MM/YYYY format. | | `demo_date` | form | string | no | Optional demo date in DD/MM/YYYY format. | ## `POST /projects/delete/{project_slug}` - Delete a project Delete a project you own; administrators may delete any user's project. Soft-deleted with all of its files (hidden everywhere but restorable from admin trash). *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project. | **Sample response** ```json { "ok": true, "redirect": "/projects", "data": null } ``` ## `POST /projects/{project_slug}/private` - Set project visibility Mark a project you own private or public. Send value=1 for private, value=0 for public. A project you hide as a member stays visible to administrators; a project you hide as an administrator is visible only to you, not to other administrators (this also hides its files and any attached containers). *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project. | | `value` | form | boolean | yes | 1 to make the project private, 0 to make it public. | ## `POST /projects/{project_slug}/readonly` - Set project read-only Mark a project you own read-only so all of its files become immutable (no writes, edits, moves, deletes, or uploads succeed), or writable again. Send value=1 for read-only, value=0 for writable. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project. | | `value` | form | boolean | yes | 1 to make the project read-only, 0 to make it writable. | ## `POST /projects/{project_slug}/zip` - Queue a project zip Start a background job that archives the whole project. Returns the job uid and status URL to poll. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project. | **Sample response** ```json { "uid": "ZIP_JOB_UID", "status_url": "/zips/ZIP_JOB_UID" } ``` ## `GET /zips/{uid}` - Zip job status Poll a zip job. While pending or running download_url is null; once done it points at the archive. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `uid` | path | string | yes | Zip job uid returned when the job was queued. | **Sample response** ```json { "uid": "ZIP_JOB_UID", "kind": "zip", "status": "done", "preferred_name": "my-project", "download_url": "/zips/ZIP_JOB_UID/download", "error": null, "bytes_in": 20480, "bytes_out": 8192, "item_count": 12, "file_count": 10, "dir_count": 2, "created_at": "2026-06-09T10:00:00+00:00", "completed_at": "2026-06-09T10:00:03+00:00" } ``` ## `GET /zips/{uid}/download` - Download a zip archive Stream the finished archive as application/zip. Each access extends the retention window. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `uid` | path | string | yes | Zip job uid of a finished job. | ## `POST /projects/{project_slug}/fork` - Queue a project fork Start a background job that copies the whole project into a new project owned by you. Returns the job uid and status URL to poll. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `project_slug` | path | string | yes | Slug or UID of the project to fork. | | `title` | form | string | yes | Title for the new forked project. | **Sample response** ```json { "uid": "FORK_JOB_UID", "status_url": "/forks/FORK_JOB_UID" } ``` ## `GET /forks/{uid}` - Fork job status Poll a fork job. While pending or running project_url is null; once done it points at the new project. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `uid` | path | string | yes | Fork job uid returned when the job was queued. | **Sample response** ```json { "uid": "FORK_JOB_UID", "kind": "fork", "status": "done", "preferred_name": "My Fork", "project_uid": "NEW_PROJECT_UID", "project_url": "/projects/new-project-slug", "source_project_uid": "SOURCE_PROJECT_UID", "error": null, "item_count": 12, "created_at": "2026-06-09T10:00:00+00:00", "completed_at": "2026-06-09T10:00:05+00:00" } ``` ## `GET /gists` - Browse gists List code gists. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `language` | query | enum | no | Filter by language. Allowed: python, javascript, typescript, html, css, c, cpp, java, go, rust, sql, bash, json, markdown, plaintext. | | `user_uid` | query | string | no | Filter by author UID. | | `search` | query | string | no | Search gist title, description, and author username. | | `before` | query | string | no | Pagination cursor. | **Sample response** ```json { "gists": [ { "gist": { "uid": "UID", "slug": "slug", "user_uid": "UID", "title": "Title", "description": "text", "source_code": "string", "language": "python", "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "updated_at": "2026-01-01T00:00:00+00:00" }, "maturity": "string", "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "my_vote": 0, "comment_count": 0, "recent_comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ] } ], "total_count": 0, "next_cursor": "2026-01-01T00:00:00+00:00", "current_language": "python", "search": "string", "languages": [ [ "python" ] ], "gist_language_codes": [ "python" ] } ``` ## `GET /gists/{gist_slug}` - View a gist Render a gist with comments. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `gist_slug` | path | string | yes | Slug or UID of the gist. | **Sample response** ```json { "maturity": "string", "gist": { "uid": "UID", "slug": "slug", "user_uid": "UID", "title": "Title", "description": "text", "source_code": "string", "language": "python", "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "updated_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "is_owner": false, "star_count": 0, "my_vote": 0, "time_ago": "2 hours ago", "comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] }, "bookmarked": false } ``` ## `POST /gists/create` - Create a gist Publish a code snippet. Redirects to the new gist. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `title` | form | string | yes | Title, 1-200 characters. | | `source_code` | form | textarea | yes | Source, 1-400000 characters. | | `language` | form | enum | no | Syntax language. Allowed: python, javascript, typescript, html, css, c, cpp, java, go, rust, sql, bash, json, markdown, plaintext. | | `description` | form | string | no | Optional description. | **Sample response** ```json { "ok": true, "redirect": "/gists/GIST_SLUG", "data": { "uid": "GIST_UID", "slug": "GIST_SLUG", "url": "/gists/GIST_SLUG" } } ``` ## `POST /gists/edit/{gist_slug}` - Edit a gist Update a gist you own. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `gist_slug` | path | string | yes | Slug or UID of the gist. | | `title` | form | string | yes | Title, 1-200 characters. | | `source_code` | form | textarea | yes | Source, 1-400000 characters. | | `language` | form | enum | no | Syntax language. Allowed: python, javascript, typescript, html, css, c, cpp, java, go, rust, sql, bash, json, markdown, plaintext. | | `description` | form | string | no | Optional description. | **Sample response** ```json { "ok": true, "redirect": "/gists/GIST_SLUG", "data": { "uid": "GIST_UID", "slug": "GIST_SLUG", "url": "/gists/GIST_SLUG" } } ``` ## `POST /gists/delete/{gist_slug}` - Delete a gist Delete a gist you own; administrators may delete any user's gist. Soft-deleted (hidden everywhere but restorable from admin trash). *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `gist_slug` | path | string | yes | Slug or UID of the gist. | **Sample response** ```json { "ok": true, "redirect": "/gists", "data": null } ``` ## `GET /news` - Browse news Curated developer news. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `before` | query | string | no | Pagination cursor (synced_at). | **Sample response** ```json { "articles": [ { "article": { "uid": "UID", "slug": "slug", "title": "Title", "description": "text", "content": "text", "url": "/path", "source_name": "string", "author": "string", "grade": 0, "ai_grade": 0, "status": "published", "image_url": "/path", "featured": 0, "has_unique_image": 0, "article_published": "string", "created_at": "2026-01-01T00:00:00+00:00", "synced_at": "2026-01-01T00:00:00+00:00" }, "time_ago": "2 hours ago", "image_url": "/path", "grade": 0, "featured": 0, "recent_comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ] } ], "next_cursor": "2026-01-01T00:00:00+00:00" } ``` ## `GET /news/{news_slug}` - View a news article Render a news article with comments. Returns an HTML page. *Minimal role:* Public **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `news_slug` | path | string | yes | Slug or UID of the article. | **Sample response** ```json { "maturity": "string", "article": { "uid": "UID", "slug": "slug", "title": "Title", "description": "text", "content": "text", "url": "/path", "source_name": "string", "author": "string", "grade": 0, "ai_grade": 0, "status": "published", "image_url": "/path", "featured": 0, "has_unique_image": 0, "article_published": "string", "created_at": "2026-01-01T00:00:00+00:00", "synced_at": "2026-01-01T00:00:00+00:00" }, "canonical_slug": "slug", "image_url": "/path", "grade": 0, "time_ago": "2 hours ago", "comments": [ { "comment": { "uid": "UID", "user_uid": "UID", "content": "text", "parent_uid": "UID", "target_type": "string", "target_uid": "UID", "created_at": "2026-01-01T00:00:00+00:00" }, "author": { "uid": "UID", "username": "username", "avatar_seed": "string", "bio": "text", "location": "string", "git_link": "string", "website": "string", "level": 0, "xp": 0, "xp_progress_pct": 0, "xp_next_level": 0, "stars": 0, "created_at": "2026-01-01T00:00:00+00:00", "last_seen": "string" }, "time_ago": "2 hours ago", "votes": { "up": 0, "down": 0 }, "my_vote": 0, "children": [], "attachments": [ { "uid": "UID", "filename": "string", "url": "/path", "size": 0, "is_image": false, "is_video": false, "mime_type": "string", "created_at": "2026-01-01T00:00:00+00:00", "can_modify": false } ], "reactions": { "counts": {}, "mine": [] } } ], "bookmarked": false } ```