curl --request POST \
--url https://clientapi.woku.app/wokus/create-woku-form-data \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'description=Customer Service Experience - Store #123' \
--form file='@example-file' \
--form folderSecondaryKey=store-123 \
--form parentFolderSecondaryKey=region-north \
--form clientEmail=customer@example.com \
--form clientPhone=56912345678import requests
url = "https://clientapi.woku.app/wokus/create-woku-form-data"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"description": "Customer Service Experience - Store #123",
"folderSecondaryKey": "store-123",
"parentFolderSecondaryKey": "region-north",
"clientEmail": "customer@example.com",
"clientPhone": "56912345678"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('description', 'Customer Service Experience - Store #123');
form.append('file', '<string>');
form.append('folderSecondaryKey', 'store-123');
form.append('parentFolderSecondaryKey', 'region-north');
form.append('clientEmail', 'customer@example.com');
form.append('clientPhone', '56912345678');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://clientapi.woku.app/wokus/create-woku-form-data', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://clientapi.woku.app/wokus/create-woku-form-data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://clientapi.woku.app/wokus/create-woku-form-data"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://clientapi.woku.app/wokus/create-woku-form-data")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://clientapi.woku.app/wokus/create-woku-form-data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"_id": "507f1f77bcf86cd799439011",
"description": "Customer Service Experience - Store #123",
"createdBy": "507f1f77bcf86cd799439012",
"companyId": "507f1f77bcf86cd799439013",
"folderId": "507f1f77bcf86cd799439014",
"file": {
"filename": "product-image.webp",
"type": "image",
"url": "https://cdn.woku.app/files/product-image.webp"
},
"qualifications": [
{
"_id": "507f1f77bcf86cd799439015",
"qualification": 5,
"createdBy": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}
],
"textnotes": [
{
"_id": "507f1f77bcf86cd799439016",
"qualification": {
"qualification": 5
},
"description": "Excellent service!",
"anonymous": false,
"feedbackType": "positive",
"clientId": "<string>",
"validated": true,
"createdAt": "2023-11-07T05:31:56Z"
}
],
"voicemails": [
{
"_id": "507f1f77bcf86cd799439017",
"qualification": {
"qualification": 4
},
"file": {
"filename": "voicemail.mp4",
"url": "<string>"
},
"transcription": "I had a great experience with your service...",
"anonymous": false,
"feedbackType": "positive",
"clientId": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}
],
"feedbacksSummary": "Customers generally praise the helpful staff and quick service...",
"closed": false,
"createdAt": "2026-01-20T10:30:00.000Z",
"updatedAt": "2026-01-20T15:45:00.000Z"
}{
"statusCode": 400,
"message": [
"description must be a string",
"fileUrl must be a valid URL"
],
"error": "Bad Request"
}{
"statusCode": 401,
"message": "Invalid or missing API key"
}Create a woku with file upload
Creates a new woku with an optional file upload using multipart form data. This endpoint is ideal when you want to upload the image directly instead of providing a URL. Supports image files (JPEG, PNG, WebP, etc.).
curl --request POST \
--url https://clientapi.woku.app/wokus/create-woku-form-data \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'description=Customer Service Experience - Store #123' \
--form file='@example-file' \
--form folderSecondaryKey=store-123 \
--form parentFolderSecondaryKey=region-north \
--form clientEmail=customer@example.com \
--form clientPhone=56912345678import requests
url = "https://clientapi.woku.app/wokus/create-woku-form-data"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"description": "Customer Service Experience - Store #123",
"folderSecondaryKey": "store-123",
"parentFolderSecondaryKey": "region-north",
"clientEmail": "customer@example.com",
"clientPhone": "56912345678"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('description', 'Customer Service Experience - Store #123');
form.append('file', '<string>');
form.append('folderSecondaryKey', 'store-123');
form.append('parentFolderSecondaryKey', 'region-north');
form.append('clientEmail', 'customer@example.com');
form.append('clientPhone', '56912345678');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://clientapi.woku.app/wokus/create-woku-form-data', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://clientapi.woku.app/wokus/create-woku-form-data",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://clientapi.woku.app/wokus/create-woku-form-data"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://clientapi.woku.app/wokus/create-woku-form-data")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://clientapi.woku.app/wokus/create-woku-form-data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nCustomer Service Experience - Store #123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"folderSecondaryKey\"\r\n\r\nstore-123\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"parentFolderSecondaryKey\"\r\n\r\nregion-north\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientEmail\"\r\n\r\ncustomer@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"clientPhone\"\r\n\r\n56912345678\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"_id": "507f1f77bcf86cd799439011",
"description": "Customer Service Experience - Store #123",
"createdBy": "507f1f77bcf86cd799439012",
"companyId": "507f1f77bcf86cd799439013",
"folderId": "507f1f77bcf86cd799439014",
"file": {
"filename": "product-image.webp",
"type": "image",
"url": "https://cdn.woku.app/files/product-image.webp"
},
"qualifications": [
{
"_id": "507f1f77bcf86cd799439015",
"qualification": 5,
"createdBy": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}
],
"textnotes": [
{
"_id": "507f1f77bcf86cd799439016",
"qualification": {
"qualification": 5
},
"description": "Excellent service!",
"anonymous": false,
"feedbackType": "positive",
"clientId": "<string>",
"validated": true,
"createdAt": "2023-11-07T05:31:56Z"
}
],
"voicemails": [
{
"_id": "507f1f77bcf86cd799439017",
"qualification": {
"qualification": 4
},
"file": {
"filename": "voicemail.mp4",
"url": "<string>"
},
"transcription": "I had a great experience with your service...",
"anonymous": false,
"feedbackType": "positive",
"clientId": "<string>",
"createdAt": "2023-11-07T05:31:56Z"
}
],
"feedbacksSummary": "Customers generally praise the helpful staff and quick service...",
"closed": false,
"createdAt": "2026-01-20T10:30:00.000Z",
"updatedAt": "2026-01-20T15:45:00.000Z"
}{
"statusCode": 400,
"message": [
"description must be a string",
"fileUrl must be a valid URL"
],
"error": "Bad Request"
}{
"statusCode": 401,
"message": "Invalid or missing API key"
}Authorizations
Company API key. Obtain this from your Woku dashboard under Settings > API Keys.
Body
Description of the woku (product, service, or experience being reviewed)
"Customer Service Experience - Store #123"
Image file to upload (JPEG, PNG, WebP, etc.)
Secondary key identifier for the folder
"store-123"
Secondary key identifier for the parent folder
"region-north"
Email address of the client for review invitation
"customer@example.com"
Phone number of the client (as string in form-data)
"56912345678"
Response
Woku created successfully with file
Unique identifier of the woku
"507f1f77bcf86cd799439011"
Description of the woku
"Customer Service Experience - Store #123"
User ID who created the woku
"507f1f77bcf86cd799439012"
Company ID the woku belongs to
"507f1f77bcf86cd799439013"
Folder ID the woku is organized in
"507f1f77bcf86cd799439014"
Show child attributes
Show child attributes
Array of star ratings
Show child attributes
Show child attributes
Array of text reviews
Show child attributes
Show child attributes
Array of voice reviews
Show child attributes
Show child attributes
AI-generated summary of all feedback
"Customers generally praise the helpful staff and quick service..."
Whether the woku is closed for new reviews
Creation timestamp
"2026-01-20T10:30:00.000Z"
Last update timestamp
"2026-01-20T15:45:00.000Z"