Coworkies API Reference
REST API for the coworking, workspace, and hospitality job board, space directory, and community platform.
https://api.coworkies.com/v2
Use the Coworkies API to:
- Post and manage remote job listings programmatically
- Search coworking spaces across 100+ cities
- Build Chrome extensions and AI agent integrations
- Access blog content and community resources
All endpoints return JSON. Authenticated endpoints require an API key sent via header, bearer token, or query parameter.
Machine-Readable Resources
| OpenAPI Spec | OpenAPI 3.1 specification for code generation, Swagger UI, and Postman import |
| llms.txt | Concise API overview optimized for AI agent context windows |
| llms-full.txt | Complete API reference with all endpoints, schemas, and examples for LLMs |
Authentication
All requests (except public endpoints) require an API key. Pro space owners can create and manage keys from the API Keys section in their space dashboard.
Key format
API keys use prefixed tokens for easy identification:
cwk_live_— Live key with read & write accesscwk_rstr_— Restricted key, read-only access
Sending your key
Scopes
Each API key is assigned permission scopes that control what it can access.
| Scope | Access |
|---|---|
read | Read all resources (jobs, spaces, cities, events, blog) |
write | Read & write all resources. Implies read. |
jobs:read | Read job listings only |
jobs:write | Create & update job listings |
spaces:read | Read space profiles |
events:read | Read events |
Space-scoped keys
Keys created from a space dashboard are automatically scoped to that space.
They will only return data belonging to that space (jobs, profile, events).
Attempting to access or modify another space’s data returns 403 Forbidden.
Public endpoints (no auth required)
-
GET /v2— API info and endpoint listing POST /v2/feedback— Submit feedback-
POST /v2/newsletters/subscribe— Newsletter signup
# Recommended: X-API-Key header
curl https://api.coworkies.com/v2/jobs \
-H "X-API-Key: your_api_key"
# Alternative: Bearer token
curl https://api.coworkies.com/v2/jobs \
-H "Authorization: Bearer your_api_key"
Response Format
All responses use a consistent JSON envelope with
success (boolean) and status (HTTP
code) fields.
Successful responses include a data object. Error
responses include an error object with
code, message, and optionally
details (array of validation messages).
{
"success": true,
"status": 200,
"data": {
"jobs": [...],
"pagination": { ... }
}
}
{
"success": false,
"status": 422,
"error": {
"code": "validation_error",
"message": "Validation failed",
"details": [
"Job title is required",
"City ID is required"
]
}
}
Error Handling
Errors follow HTTP conventions. The
error.code field provides a machine-readable
identifier for programmatic handling.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed request body or invalid JSON |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Valid key but insufficient permissions |
| 404 | not_found | Endpoint or resource not found |
| 405 | method_not_allowed | HTTP method not supported on this endpoint |
| 409 | conflict | Resource conflict (e.g. duplicate) |
| 422 | validation_error | Validation failed (see error.details array) |
| 429 | rate_limit_exceeded | Too many requests — back off and retry |
| 500 | server_error | Internal server error |
const response = await fetch('https://api.coworkies.com/v2/jobs', {
headers: { 'X-API-Key': 'your_api_key' }
});
const json = await response.json();
if (!json.success) {
console.error(`${json.error.code}: ${json.error.message}`);
if (json.error.details) {
json.error.details.forEach(d => console.error(` - ${d}`));
}
}
Pagination
By default, GET /v2/jobs returns all active jobs
with a total count. When pagination is enabled
server-side, use page and
per_page query parameters.
| Param | Type | Description |
|---|---|---|
| page | int | Page number (default: 1) |
| per_page | int | Items per page, max 50 (default: 20) |
{
"data": {
"jobs": [...],
"pagination": {
"total": 142,
"limit": 20,
"offset": 0,
"current_count": 20,
"total_pages": 8,
"current_page": 1,
"has_next": true,
"has_previous": false
}
}
}
Rate Limiting
Default limits per API key:
- 60 requests/minute
- 1,000 requests/hour
Verified integrations may receive higher limits (120 requests/minute).
When rate limited, you'll receive a 429 response.
Implement exponential backoff with jitter for retries.
Jobs
List Jobs
Returns active job postings with filtering, search, and optional pagination.
Query Parameters
| Param | Type | Description |
|---|---|---|
| page | int | Page number (default: 1) |
| per_page | int | Items per page, max 50 (default: 20) |
| q | string | Search title, company, or tags |
| job_type | string | fulltime parttime freelance internship |
| remote | bool | Filter remote-only jobs (1 or true) |
| city | string | Filter by city slug (e.g. berlin) |
curl "https://api.coworkies.com/v2/jobs?q=developer&remote=1&per_page=5" \
-H "X-API-Key: your_api_key"
{
"success": true,
"status": 200,
"data": {
"jobs": [
{
"id_job": 1234,
"title": "Remote Software Developer",
"company": "Tech Solutions Inc.",
"job_type": "fulltime",
"tags": "javascript,react,node",
"is_remote": true,
"page_url": "remote-software-developer-1234",
"external_url": "https://example.com/apply?ref=coworkiesjobs",
"apply_url": "https://example.com/careers/apply",
"company_logo": "logo_1234.png",
"date_added": "2026-05-15T10:30:00Z",
"expiration_date": "2026-06-15T00:00:00Z",
"city_name": "Berlin",
"city_slug": "berlin",
"space_name": null,
"sal_min": "65000",
"sal_max": "85000",
"currency": "EUR",
"url": "https://www.coworkies.com/jobs/remote-software-developer-1234/details"
}
],
"pagination": {
"total": 42,
"current_page": 1,
"has_next": true
}
}
}
Create Job
Create a new job posting. Requires jobs:write or write scope.
The job is automatically assigned to your API key’s space. Job status and publishing behavior depends on your space’s plan.
Deduplication: A fingerprint is computed from normalized (title + company + city + external_url). If a matching job exists, it is updated instead of duplicated. The response action field indicates "created" or "updated".
Request Body (JSON)
| Field | Type | Description |
|---|---|---|
| title required | string | Job title |
| company required | string | Company name |
| description required | string | Job description (plain text or basic HTML: p, br, ul, ol, li, h2, h3, strong, em, a) |
| job_type required | string | fulltime parttime freelance internship |
| id_city required* | int | City ID from GET /v2/cities. Required unless city_name provided. |
| city_name required* | string | City name (e.g. "Berlin"). Resolved to id_city server-side. Use this OR id_city. |
| tags required | string | Comma-separated tags (e.g. "react,node,remote"). Normalized: trimmed, lowercased, deduplicated. |
| external_url optional | string | Link to original job listing source. ?ref=coworkiesjobs is appended automatically. |
| apply_url optional | string | Direct application link for candidates (separate from source URL). |
| is_remote optional | int | 0 or 1 (default: 0) |
| inv_email optional | string | Contact email for notifications. Must be valid email format. |
| currency optional | string | EUR USD GBP (default: EUR) |
| sal_min optional | int | Minimum annual salary |
| sal_max optional | int | Maximum annual salary |
| id_space optional | int | Associated coworking space ID (must be confirmed) |
| id_plan optional | int | Pricing plan ID (default: 5 = free). Must be active. |
id_city (integer) or city_name (string). The API tries exact match first, then prefix match. The resolved city is returned as city.id and city.name.
sal_min cannot exceed sal_max. Currency must be EUR, USD, or GBP. The external_url is validated and gets ?ref=coworkiesjobs appended. Invalid inv_email falls back to a default. Status is always draft (server-enforced).
curl https://api.coworkies.com/v2/jobs \
-X POST \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Community Manager",
"company": "Coworking Studio",
"description": "Lead member experience at our Berlin location.",
"job_type": "fulltime",
"city_name": "Berlin",
"tags": "community,events,hospitality",
"external_url": "https://example.com/careers/cm",
"apply_url": "https://example.com/careers/cm/apply",
"is_remote": 0,
"currency": "EUR",
"sal_min": 35000,
"sal_max": 45000
}'
{
"success": true,
"status": 201,
"data": {
"job_id": 567,
"page_url": "community-manager-567",
"hash_identifier": "a1b2c3d4e5f6...",
"status": "active",
"action": "created",
"dedupe_hash": "f7a8b9...",
"is_paid": true,
"city": { "id": 42, "name": "Berlin" },
"apply_url": null,
"plan_price": 0,
"expiration_days": 30,
"message": "Job created and published successfully.",
"view_url": "https://www.coworkies.com/jobs/community-manager-567/details",
"payment_url": null,
"edit_url": "https://www.coworkies.com/jobs/community-manager-567/edit?job_hash=a1b2c3...",
"unpublish_url": "https://www.coworkies.com/jobs/community-manager-567/unpublish?job_hash=a1b2c3..."
}
}
Implement a function to create a job posting via the Coworkies API.
POST https://api.coworkies.com/v2/jobs
Headers: X-API-Key: your_api_key, Content-Type: application/json
Required fields:
- title: string (job title)
- company: string (company name)
- description: string (supports HTML: p, br, ul, ol, li, h2, h3, strong, em, a)
- job_type: "fulltime" | "parttime" | "freelance" | "internship"
- tags: string (comma-separated, auto-normalized: trimmed, lowercased, deduplicated)
- City: provide EITHER id_city (int) OR city_name (string, resolved server-side via exact then prefix match)
Optional fields:
- external_url: string (source URL, gets ?ref=coworkiesjobs appended)
- apply_url: string (direct application link for candidates)
- is_remote: 0 | 1 (default 0)
- inv_email: string (valid email for notifications)
- currency: "EUR" | "USD" | "GBP" (default EUR)
- sal_min: int (annual salary min)
- sal_max: int (must be >= sal_min)
- id_space: int (coworking space, must exist and be confirmed)
- id_plan: int (default 5 = free plan)
Deduplication: API computes SHA-256 hash of (title + company + city_id + external_url). If match found, existing job is UPDATED (response action="updated"), otherwise new job is CREATED (action="created").
Requires scope: jobs:write or write.
Job is auto-assigned to your API key's space. Status depends on your plan.
Success response (201):
{ success: true, data: { job_id: int, page_url: string, hash_identifier: string, status: "active"|"draft", action: "created"|"updated", dedupe_hash: string, is_paid: bool, city: { id: int, name: string }, apply_url: string|null, plan_price: int, expiration_days: int, message: string, view_url: string|null, payment_url: string|null, edit_url: string, unpublish_url: string } }
Error response (422):
{ success: false, error: { code: "validation_error", message: "Validation failed", details: ["error 1", "error 2"] } }
Cities
List Cities
Returns confirmed cities. Use search for autocomplete when resolving id_city for job creation.
Query Parameters
| Param | Type | Description |
|---|---|---|
| q | string | Exact match on city slug |
| search | string | Partial name match (e.g. berl) |
curl "https://api.coworkies.com/v2/cities?search=berlin" \
-H "X-API-Key: your_api_key"
{
"success": true,
"status": 200,
"data": [
{
"id_city": "42",
"city_name": "Berlin",
"city_slug": "berlin",
"latitude": "52.5200",
"longitude": "13.4050"
}
]
}
Spaces
List Spaces
Returns confirmed coworking spaces. Filter by city slug.
Query Parameters
| Param | Type | Description |
|---|---|---|
| q | string | Filter by city slug (e.g. berlin) |
curl "https://api.coworkies.com/v2/spaces?q=berlin" \
-H "X-API-Key: your_api_key"
{
"success": true,
"data": [
{
"space_name": "Example Coworking",
"space_url": "example-coworking",
"space_address": "Sample Street 12",
"latitude": "52.5200",
"longitude": "13.4050",
"city_name": "Berlin"
}
]
}
City Spaces
Returns all confirmed spaces with city metadata and LinkedIn URLs. Ideal for directory-style views.
Blog
List Blog Posts
Returns blog posts with category/tag filtering and pagination.
Query Parameters
| Param | Type | Description |
|---|---|---|
| category | string | Filter by category |
| tag | string | Filter by tag |
| limit | int | Results per page, max 50 (default: 10) |
| offset | int | Skip N results (default: 0) |
| slug | string | Fetch single post by slug |
curl "https://api.coworkies.com/v2/blog?category=careers&limit=5" \
-H "X-API-Key: your_api_key"
Get Blog Post
Returns a single blog post by its slug URL.
{
"success": true,
"data": {
"title": "Launching The Coworking Salary Survey 2026",
"slug_url": "launching-the-coworking-salary-survey-6",
"categories": ["careers"],
"tags": ["coworking-career", "coworking-jobs"],
"date": "2026-03-07T13:29:51Z",
"authors": [{
"name": "Pauline Roussel",
"username": "pauline"
}],
"reading_time": 5
}
}
Health Check
Returns API status, PHP version, memory usage, and Redis connectivity. Useful for monitoring.
{
"success": true,
"data": {
"status": "ok",
"php_version": "8.4.0",
"memory_usage": 2097152,
"redis": {
"status": "connected",
"version": "7.0.4"
}
}
}
Feedback
Submit feedback (no authentication required). Accepts JSON or form-encoded body.
Body Parameters
| Field | Type | Description |
|---|---|---|
| message required | string | Feedback message |
| email optional | string | Contact email |
| url optional | string | Page URL for context |
| category optional | string | Feedback category |
Quick Start
Get up and running in under 2 minutes.
1. Get an API key
Email [email protected] to request access.
2. Make your first request
Fetch active job listings to verify your key works.
3. Post a job
Use city_name to skip the city ID lookup — the API resolves it automatically.
4. Integrate in your app
Use the response data to build your integration.
curl "https://api.coworkies.com/v2/jobs?per_page=5" \
-H "X-API-Key: your_api_key"
curl https://api.coworkies.com/v2/jobs \
-X POST \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Frontend Developer",
"company": "Remote Co",
"description": "Build beautiful interfaces.",
"job_type": "fulltime",
"city_name": "Lisbon",
"tags": "react,typescript,remote",
"is_remote": 1
}'
async function postJob(jobData) {
const response = await fetch(
'https://api.coworkies.com/v2/jobs',
{
method: 'POST',
headers: {
'X-API-Key': 'your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify(jobData),
}
);
const result = await response.json();
if (!result.success) {
throw new Error(result.error.message);
}
return result.data;
}