curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/chat/message \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"content": "Add a contact form to the home page"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/chat/message"
payload = { "content": "Add a contact form to the home page" }
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({content: 'Add a contact form to the home page'})
};
fetch('https://app.base44.com/api/apps/{app_id}/chat/message', 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://app.base44.com/api/apps/{app_id}/chat/message",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'content' => 'Add a contact form to the home page'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api_key: <api-key>"
],
]);
$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://app.base44.com/api/apps/{app_id}/chat/message"
payload := strings.NewReader("{\n \"content\": \"Add a contact form to the home page\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api_key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/chat/message")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"content\": \"Add a contact form to the home page\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/chat/message")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"content\": \"Add a contact form to the home page\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6820f3a4e7b91d003c45a1f2",
"name": "My CRM",
"status": {
"state": "ready",
"details": "Publishing app",
"request_id": "a1b2c3d4e5f67890abcdef12",
"last_updated_date": "2026-08-02T14:30:00Z",
"error_source": "build",
"paywall_context": {
"billing_organization_id": "67e0b12c4d8a3f005b21c9e4",
"user_id": "6706af53b9c1e2004a37d85f",
"evaluated_at": "2026-08-02T14:30:00Z"
}
},
"conversation": {
"id": "1f0c2b7a-9d51-4c3e-8a62-7b4d5e6f8a90",
"messages": [
{
"id": "7f3a1c88-52d4-4a0e-9b31-2c6f0d8e4a19",
"role": "assistant",
"content": "I added a contact form to the home page.",
"file_urls": [
"https://example.com/mockup.png"
],
"hidden": false,
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"tool_calls": [
{
"id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"name": "create_file",
"status": "waiting_for_user_input",
"requires_user_input": true,
"arguments_string": "{\"file_path\": \"src/pages/Home.jsx\", \"content\": \"export default function Home() {}\"}"
}
],
"usage": {
"prompt_tokens": 18432,
"completion_tokens": 742,
"credits_charged": 1.5
},
"metadata": {
"created_date": "2026-08-02T14:30:00",
"created_by_email": "developer@example.com"
}
}
]
}
}Send chat message
Sends a message to the app’s AI chat and runs the turn it starts. Each turn consumes credits. This is how you build an app after creating it.
Set an X-Request-ID header before you send. A network retry carrying the same value is ignored rather than run a second time and charged again.
The request stays open until the AI finishes the whole turn, so it can take several minutes on a large change. The response is the app once the turn settles, with the messages the turn produced under conversation.messages. That list is ordered oldest first, so the AI’s reply is the last entry whose role is assistant.
A 200 response does not mean the turn succeeded, and it does not always describe a turn. Three cases come back as a 200.
- The turn ran and finished.
status.stateisreadyand the app is idle again. - The turn ran and failed.
status.stateiserror, andstatus.error_sourcesays where it failed. A value ofpaywallmeans the app’s workspace has no credits left and no work was done. - The message was queued. The AI was already busy with an earlier message, so the response is
{"queued": true}with the queue’s state and none of the fields below. Check forqueuedbefore you read anything else.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/chat/message \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"content": "Add a contact form to the home page"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/chat/message"
payload = { "content": "Add a contact form to the home page" }
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({content: 'Add a contact form to the home page'})
};
fetch('https://app.base44.com/api/apps/{app_id}/chat/message', 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://app.base44.com/api/apps/{app_id}/chat/message",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'content' => 'Add a contact form to the home page'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"api_key: <api-key>"
],
]);
$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://app.base44.com/api/apps/{app_id}/chat/message"
payload := strings.NewReader("{\n \"content\": \"Add a contact form to the home page\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api_key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/chat/message")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"content\": \"Add a contact form to the home page\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/chat/message")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"content\": \"Add a contact form to the home page\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6820f3a4e7b91d003c45a1f2",
"name": "My CRM",
"status": {
"state": "ready",
"details": "Publishing app",
"request_id": "a1b2c3d4e5f67890abcdef12",
"last_updated_date": "2026-08-02T14:30:00Z",
"error_source": "build",
"paywall_context": {
"billing_organization_id": "67e0b12c4d8a3f005b21c9e4",
"user_id": "6706af53b9c1e2004a37d85f",
"evaluated_at": "2026-08-02T14:30:00Z"
}
},
"conversation": {
"id": "1f0c2b7a-9d51-4c3e-8a62-7b4d5e6f8a90",
"messages": [
{
"id": "7f3a1c88-52d4-4a0e-9b31-2c6f0d8e4a19",
"role": "assistant",
"content": "I added a contact form to the home page.",
"file_urls": [
"https://example.com/mockup.png"
],
"hidden": false,
"checkpoint_id": "6886b8d390dc7e2f4a2c91b3",
"tool_calls": [
{
"id": "toolu_01A9FJd3kP2mNqRs7VwXyZ4b",
"name": "create_file",
"status": "waiting_for_user_input",
"requires_user_input": true,
"arguments_string": "{\"file_path\": \"src/pages/Home.jsx\", \"content\": \"export default function Home() {}\"}"
}
],
"usage": {
"prompt_tokens": 18432,
"completion_tokens": 742,
"credits_charged": 1.5
},
"metadata": {
"created_date": "2026-08-02T14:30:00",
"created_by_email": "developer@example.com"
}
}
]
}
}Authorizations
Personal API key.
Path Parameters
ID of the app whose AI chat this request acts on.
Body
What you want the AI to do. Up to 100,000 characters.
"Add a contact form to the home page"
Publicly reachable URLs of files to attach to the message, such as a screenshot or a mockup for the AI to work from. Base44 downloads each file, so a URL has to resolve without credentials.
["https://example.com/mockup.png"]
Response
Successful Response
An app, with its conversation and build status.
ID of the app.
"6820f3a4e7b91d003c45a1f2"
Display name of the app.
"My CRM"
The app's build status once the request returned. Read state to tell a finished turn from one that is still processing or that failed.
Show child attributes
Show child attributes
The app's conversation, including the messages this request produced.
Show child attributes
Show child attributes
Was this page helpful?