> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://api.docs.modulards.com/modular-ds-public-api/tasks/website-tasks/create-tasks-on-websites/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://api.docs.modulards.com/_mcp/server. # Create tasks on websites POST https://api.modulards.com/api/public/v1/site-tasks Content-Type: application/json Logs the same task on each website you list in `sites`, up to 50. Use it to record work such as "renewed the SSL certificate" on every website it touched. One task is created for each website. Websites that cannot be processed are reported in `meta.skipped`, each with a `reason_code` and a message, and do not fail the call. Only a website your token cannot reach is skipped (`PERMISSION_DENIED`, with a null `site_name`), because a task does not need a connected website. When every website was skipped, the answer is `200` with an empty list instead of `201`. Attached files are moved onto the first task created. Every other task receives its own copy a few seconds later. A file that could not be attached is reported in `meta.warnings` and does not fail the call. The answer does not include the attachments: read a task with "Retrieve a task" and `include=files` to see them. Your role must be allowed to create tasks; without it the request answers 404. **Body** * `sites` (array of integers, required): ids of the websites to act on, 1 to 50. * `title` (string, required): at most 255 characters. * `date` (string, required): the day the work happened, as `YYYY-MM-DD`. * `content` (string, optional): what was done, as HTML. It is cleaned on the server and holds at most 2500 characters once tags are stripped. * `time_spent` (number, optional): minutes spent, decimals allowed, 0 or more. * `is_pending` (boolean, optional): `false` when omitted. * `files` (array, optional): up to 4 entries of `{uuid, name}`. `uuid` is the id returned by "Upload a file" (the only source a new task can take files from); `name` is an optional display name of at most 255 characters. **Errors** * **422**: `sites` is missing, empty, has more than 50 ids, repeats an id or contains an id that is not a website; `title` or `date` is missing; a `files.*.uuid` is unknown or was not uploaded by you. Reference: https://api.docs.modulards.com/modular-ds-public-api/tasks/website-tasks/create-tasks-on-websites ## Authentication - `Authorization` header (bearer token, required) — Personal access token created in the Modular DS dashboard; read-only tokens can only call GET endpoints. ## Request ### Body (application/json) This endpoint expects an object. - `content` (string, optional) - `date` (string, optional) - `files` (list of ApiPublicV1SiteTasksPostRequestBodyContentApplicationJsonSchemaFilesItems, optional) - `is_pending` (boolean, optional) - `sites` (list of double, optional) - `time_spent` (double, optional) - `title` (string, optional) ## Response ### 200 200 OK - every website was skipped - `data` (list of any, optional) - `jsonapi` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaJsonapi, optional) - `meta` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaMeta, optional) ### 201 201 Created - one task logged, one website skipped - `data` (list of ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItems, optional) - `jsonapi` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaJsonapi, optional) - `meta` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaMeta, optional) ## Types ### ApiPublicV1SiteTasksPostRequestBodyContentApplicationJsonSchemaFilesItems - `name` (string, optional) - `uuid` (string, optional) ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaJsonapi - `version` (string, optional) ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaMeta - `skipped` (list of ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaMetaSkippedItems, optional) - `warnings` (list of string, optional) — Sentence for each attached file that could not be attached; present only when there is one. ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItems - `attributes` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItemsAttributes, optional) - `id` (string, optional) - `links` (ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItemsLinks, optional) - `type` (string, optional) ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaMetaSkippedItems - `message` (string, optional) — Sentence explaining the reason. - `reason_code` (string, optional) — Why it was skipped, for example `PERMISSION_DENIED`. - `site_id` (integer, optional, nullable) — Id of the website that was skipped; null when the entry is not about a website. - `site_name` (string, optional, nullable) — Name of the skipped website, when known. - `site_task_id` (integer, optional, nullable) — Always null for a skipped website: no task was created. ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItemsAttributes - `content` (string, optional) - `created_at` (string, optional) - `date` (string, optional) - `is_pending` (boolean, optional) - `site_id` (double, optional) - `time_spent` (double, optional) - `title` (string, optional) - `updated_at` (string, optional) ### ApiPublicV1SiteTasksPostResponsesContentApplicationJsonSchemaDataItemsLinks - `self` (string, optional) ## Examples ### 200 OK - every website was skipped **Response** ```json { "data": [], "jsonapi": { "version": "1.1" }, "meta": { "skipped": [ { "message": "Website 13 is outside your access; it was not touched.", "reason_code": "PERMISSION_DENIED", "site_id": 13, "site_name": null, "site_task_id": null } ] } } ``` **SDK Code** ```python 200 OK - every website was skipped import requests url = "https://api.modulards.com/api/public/v1/site-tasks" headers = {"Authorization": "Bearer "} response = requests.post(url, headers=headers) print(response.json()) ``` ```javascript 200 OK - every website was skipped const url = 'https://api.modulards.com/api/public/v1/site-tasks'; const options = {method: 'POST', headers: {Authorization: 'Bearer '}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go 200 OK - every website was skipped package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.modulards.com/api/public/v1/site-tasks" req, _ := http.NewRequest("POST", url, nil) req.Header.Add("Authorization", "Bearer ") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby 200 OK - every website was skipped require 'uri' require 'net/http' url = URI("https://api.modulards.com/api/public/v1/site-tasks") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' response = http.request(request) puts response.read_body ``` ```java 200 OK - every website was skipped import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.modulards.com/api/public/v1/site-tasks") .header("Authorization", "Bearer ") .asString(); ``` ```php 200 OK - every website was skipped request('POST', 'https://api.modulards.com/api/public/v1/site-tasks', [ 'headers' => [ 'Authorization' => 'Bearer ', ], ]); echo $response->getBody(); ``` ```csharp 200 OK - every website was skipped using RestSharp; var client = new RestClient("https://api.modulards.com/api/public/v1/site-tasks"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); IRestResponse response = client.Execute(request); ``` ```swift 200 OK - every website was skipped import Foundation let headers = ["Authorization": "Bearer "] let request = NSMutableURLRequest(url: NSURL(string: "https://api.modulards.com/api/public/v1/site-tasks")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` ### 201 Created - one task logged, one website skipped **Response** ```json { "data": [ { "attributes": { "content": "

Renewed the certificate through the hosting panel.

", "created_at": "2026-09-17T09:00:00.000000Z", "date": "2026-09-17", "is_pending": false, "site_id": 12, "time_spent": 30, "title": "Renew the SSL certificate", "updated_at": "2026-09-17T09:00:00.000000Z" }, "id": "501", "links": { "self": "{{base_url}}/api/public/v1/site-tasks/501" }, "type": "site-tasks" } ], "jsonapi": { "version": "1.1" }, "meta": { "skipped": [ { "message": "Website 13 is outside your access; it was not touched.", "reason_code": "PERMISSION_DENIED", "site_id": 13, "site_name": null, "site_task_id": null } ] } } ``` **SDK Code** ```python 201 Created - one task logged, one website skipped import requests url = "https://api.modulards.com/api/public/v1/site-tasks" headers = {"Authorization": "Bearer "} response = requests.post(url, headers=headers) print(response.json()) ``` ```javascript 201 Created - one task logged, one website skipped const url = 'https://api.modulards.com/api/public/v1/site-tasks'; const options = {method: 'POST', headers: {Authorization: 'Bearer '}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go 201 Created - one task logged, one website skipped package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.modulards.com/api/public/v1/site-tasks" req, _ := http.NewRequest("POST", url, nil) req.Header.Add("Authorization", "Bearer ") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby 201 Created - one task logged, one website skipped require 'uri' require 'net/http' url = URI("https://api.modulards.com/api/public/v1/site-tasks") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' response = http.request(request) puts response.read_body ``` ```java 201 Created - one task logged, one website skipped import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.modulards.com/api/public/v1/site-tasks") .header("Authorization", "Bearer ") .asString(); ``` ```php 201 Created - one task logged, one website skipped request('POST', 'https://api.modulards.com/api/public/v1/site-tasks', [ 'headers' => [ 'Authorization' => 'Bearer ', ], ]); echo $response->getBody(); ``` ```csharp 201 Created - one task logged, one website skipped using RestSharp; var client = new RestClient("https://api.modulards.com/api/public/v1/site-tasks"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); IRestResponse response = client.Execute(request); ``` ```swift 201 Created - one task logged, one website skipped import Foundation let headers = ["Authorization": "Bearer "] let request = NSMutableURLRequest(url: NSURL(string: "https://api.modulards.com/api/public/v1/site-tasks")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` ### Create tasks on websites **Request** ```json { "content": "Renewed the certificate through the hosting panel.", "date": "2026-09-17", "files": [ { "name": "invoice.png", "uuid": "9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f" } ], "is_pending": false, "sites": [ 12, 13 ], "time_spent": 30, "title": "Renew the SSL certificate" } ``` **Response** ```json { "data": [], "jsonapi": { "version": "1.1" }, "meta": { "skipped": [ { "message": "Website 13 is outside your access; it was not touched.", "reason_code": "PERMISSION_DENIED", "site_id": 13, "site_name": null, "site_task_id": null } ] } } ``` **SDK Code** ```python Create tasks on websites import requests url = "https://api.modulards.com/api/public/v1/site-tasks" payload = { "content": "Renewed the certificate through the hosting panel.", "date": "2026-09-17", "files": [ { "name": "invoice.png", "uuid": "9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f" } ], "is_pending": False, "sites": [12, 13], "time_spent": 30, "title": "Renew the SSL certificate" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Create tasks on websites const url = 'https://api.modulards.com/api/public/v1/site-tasks'; const options = { method: 'POST', headers: {Authorization: 'Bearer ', 'Content-Type': 'application/json'}, body: '{"content":"Renewed the certificate through the hosting panel.","date":"2026-09-17","files":[{"name":"invoice.png","uuid":"9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f"}],"is_pending":false,"sites":[12,13],"time_spent":30,"title":"Renew the SSL certificate"}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Create tasks on websites package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.modulards.com/api/public/v1/site-tasks" payload := strings.NewReader("{\n \"content\": \"Renewed the certificate through the hosting panel.\",\n \"date\": \"2026-09-17\",\n \"files\": [\n {\n \"name\": \"invoice.png\",\n \"uuid\": \"9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f\"\n }\n ],\n \"is_pending\": false,\n \"sites\": [\n 12,\n 13\n ],\n \"time_spent\": 30,\n \"title\": \"Renew the SSL certificate\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Create tasks on websites require 'uri' require 'net/http' url = URI("https://api.modulards.com/api/public/v1/site-tasks") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"content\": \"Renewed the certificate through the hosting panel.\",\n \"date\": \"2026-09-17\",\n \"files\": [\n {\n \"name\": \"invoice.png\",\n \"uuid\": \"9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f\"\n }\n ],\n \"is_pending\": false,\n \"sites\": [\n 12,\n 13\n ],\n \"time_spent\": 30,\n \"title\": \"Renew the SSL certificate\"\n}" response = http.request(request) puts response.read_body ``` ```java Create tasks on websites import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.modulards.com/api/public/v1/site-tasks") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"content\": \"Renewed the certificate through the hosting panel.\",\n \"date\": \"2026-09-17\",\n \"files\": [\n {\n \"name\": \"invoice.png\",\n \"uuid\": \"9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f\"\n }\n ],\n \"is_pending\": false,\n \"sites\": [\n 12,\n 13\n ],\n \"time_spent\": 30,\n \"title\": \"Renew the SSL certificate\"\n}") .asString(); ``` ```php Create tasks on websites request('POST', 'https://api.modulards.com/api/public/v1/site-tasks', [ 'body' => '{ "content": "Renewed the certificate through the hosting panel.", "date": "2026-09-17", "files": [ { "name": "invoice.png", "uuid": "9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f" } ], "is_pending": false, "sites": [ 12, 13 ], "time_spent": 30, "title": "Renew the SSL certificate" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp Create tasks on websites using RestSharp; var client = new RestClient("https://api.modulards.com/api/public/v1/site-tasks"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"content\": \"Renewed the certificate through the hosting panel.\",\n \"date\": \"2026-09-17\",\n \"files\": [\n {\n \"name\": \"invoice.png\",\n \"uuid\": \"9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f\"\n }\n ],\n \"is_pending\": false,\n \"sites\": [\n 12,\n 13\n ],\n \"time_spent\": 30,\n \"title\": \"Renew the SSL certificate\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Create tasks on websites import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = [ "content": "Renewed the certificate through the hosting panel.", "date": "2026-09-17", "files": [ [ "name": "invoice.png", "uuid": "9c6a0b1e-3f2d-4b7a-9e21-1a2b3c4d5e6f" ] ], "is_pending": false, "sites": [12, 13], "time_spent": 30, "title": "Renew the SSL certificate" ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.modulards.com/api/public/v1/site-tasks")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```