Hi Nagisa
If I share some code with you can you see what it does not work. I have tried everything to get an HTTP Request working in a script. I have also tried ChatGPT, Claaud, Gemini and I still cannot get the script action to send a PATCH to AITable. Below is a diagnostic script that shows errors in trying to make an HTTP POST.
// Complete AITable API diagnostic script
(async () => {
const baseUrl = "https://aitable.ai";
const databaseId = "dsty5rpZZZ"; // Replace with real ID
const recordId = "recXExXXX"; // Replace with real ID
const apiKey = "XXX"; // Replace with your COMPLETE API key
const results = {
timestamp: new Date().toISOString(),
tests: [],
summary: {}
};
// Test 1: API Key format check
results.tests.push({
name: "API Key Format",
result: {
length: apiKey.length,
starts_with: apiKey.substring(0, 10) + "...",
contains_spaces: apiKey.includes(" "),
is_placeholder: apiKey === "usk7X..." || apiKey.includes("..."),
diagnosis: apiKey === "usk7X..." || apiKey.includes("...") ?
"PLACEHOLDER DETECTED - You need to use your actual full API key" :
"Format looks reasonable"
}
});
// Test 2: Basic GET request to list records
try {
const getUrl = `${baseUrl}/fusion/v1/datasheets/${databaseId}/records?maxRecords=1`;
const getResponse = await fetch(getUrl, {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
const getStatus = getResponse.status;
const getStatusText = getResponse.statusText;
if (getResponse.ok) {
const getData = await getResponse.json();
results.tests.push({
name: "GET Records Test",
success: true,
status: getStatus,
statusText: getStatusText,
message: "API key works for reading data",
recordCount: getData.data?.records?.length || 0,
hasTargetRecord: getData.data?.records?.some(r => r.recordId === recordId) || false
});
} else {
const errorText = await getResponse.text();
results.tests.push({
name: "GET Records Test",
success: false,
status: getStatus,
statusText: getStatusText,
errorBody: errorText,
diagnosis: getStatus === 401 ? "API key invalid/expired" :
getStatus === 403 ? "API key lacks read permissions" :
getStatus === 404 ? "Database ID not found" : "Other error"
});
}
} catch (error) {
results.tests.push({
name: "GET Records Test",
success: false,
error: error.message,
diagnosis: "Network/CORS error"
});
}
// Test 3: Try to get the specific record
try {
const recordUrl = `${baseUrl}/fusion/v1/datasheets/${databaseId}/records/${recordId}`;
const recordResponse = await fetch(recordUrl, {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
if (recordResponse.ok) {
const recordData = await recordResponse.json();
results.tests.push({
name: "GET Specific Record Test",
success: true,
status: recordResponse.status,
message: "Target record found",
recordData: recordData,
hasCallsMadeField: recordData.data?.fields?.hasOwnProperty("Calls Made") || false
});
} else {
const errorText = await recordResponse.text();
results.tests.push({
name: "GET Specific Record Test",
success: false,
status: recordResponse.status,
statusText: recordResponse.statusText,
errorBody: errorText,
diagnosis: recordResponse.status === 404 ? "Record ID not found" : "Other error"
});
}
} catch (error) {
results.tests.push({
name: "GET Specific Record Test",
success: false,
error: error.message,
diagnosis: "Network/CORS error"
});
}
// Test 4: Check if we can get datasheet metadata
try {
const metaUrl = `${baseUrl}/fusion/v1/datasheets/${databaseId}`;
const metaResponse = await fetch(metaUrl, {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
if (metaResponse.ok) {
const metaData = await metaResponse.json();
results.tests.push({
name: "Datasheet Metadata Test",
success: true,
status: metaResponse.status,
message: "Can access datasheet metadata",
fields: metaData.data?.fields?.map(f => f.name) || []
});
} else {
const errorText = await metaResponse.text();
results.tests.push({
name: "Datasheet Metadata Test",
success: false,
status: metaResponse.status,
statusText: metaResponse.statusText,
errorBody: errorText
});
}
} catch (error) {
results.tests.push({
name: "Datasheet Metadata Test",
success: false,
error: error.message
});
}
// Generate summary
const successfulTests = results.tests.filter(t => t.success).length;
const totalTests = results.tests.length;
results.summary = {
testsRun: totalTests,
testsSuccessful: successfulTests,
overallStatus: successfulTests === 0 ? "FAILED" :
successfulTests === totalTests ? "PASSED" : "PARTIAL",
recommendations: []
};
// Add recommendations based on results
const apiKeyTest = results.tests.find(t => t.name === "API Key Format");
if (apiKeyTest?.result?.is_placeholder) {
results.summary.recommendations.push("CRITICAL: Replace 'usk7X...' with your actual complete API key");
}
const getTest = results.tests.find(t => t.name === "GET Records Test");
if (getTest && !getTest.success && getTest.status === 401) {
results.summary.recommendations.push("API key is invalid or expired - generate a new one");
}
if (getTest && !getTest.success && getTest.status === 403) {
results.summary.recommendations.push("API key lacks permissions - ensure it has read/write access");
}
if (getTest && !getTest.success && getTest.status === 404) {
results.summary.recommendations.push("Database ID 'dsty5rpeetfGMQU1nq' not found - verify it's correct");
}
const recordTest = results.tests.find(t => t.name === "GET Specific Record Test");
if (recordTest && !recordTest.success && recordTest.status === 404) {
results.summary.recommendations.push("Record ID 'recXExJTn5z9j' not found - verify it exists");
}
if (successfulTests === 0) {
results.summary.recommendations.push("Start by getting a valid API key from AITable settings");
}
return results;
})();
The output is the following:
Output:{
timestamp:
"2025-07-07T15:29:59.708Z"
tests:[
0:{
name:
"API Key Format"
result:{
length:
23
starts_with:
"XXX"
contains_spaces:
false
is_placeholder:
false
diagnosis:
"Format looks reasonable"
}
}
1:{
name:
"GET Records Test"
success:
false
error:
"Invalid URL"
diagnosis:
"Network/CORS error"
}
2:{
name:
"GET Specific Record Test"
success:
false
error:
"Invalid URL"
diagnosis:
"Network/CORS error"
}
3:{
name:
"Datasheet Metadata Test"
success:
false
error:
"Invalid URL"
}
]
summary:{
testsRun:
4
testsSuccessful:
0
overallStatus:
"FAILED"
recommendations:[
0
:
"Start by getting a valid API key from AITable settings"
]
}
}
This is using the same API key that I have been using (and still works) in the HTTP Actions.
Any guidance or some example code to patch an AITable record would be great. Do you know when the integration with AITable will be available and usable?
Thanks
Ben