Upload via API
Upload files locally present or from public remote URL via API
Sample code to upload files via API is listed below.
Assumes http://localhost:8080/
as the base URL for the API calls.
Upload local file (single)
Javascript
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
(async () => {
// API Token for uploading the file
// Reference : https://docs.nocodb.com/account-settings/api-tokens/#create-api-token
const apiToken = 'YOUR_API_TOKEN';
// Base URL for the API
const baseURL = 'https://app.nocodb.com';
// Table ID
// Table ID of your table can be retrieved from the URL (OR) by using table context menu
const tableID = 'YOUR_TABLE_ID';
// Read the image file
const photoStream = fs.createReadStream('./photo.png');
// Create form data
const formData = new FormData();
formData.append('file', photoStream);
// Define headers for uploading the file
const uploadHeaders = {
'xc-token': apiToken,
...formData.getHeaders(),
};
// Upload the file
const uploadResponse = await axios.post(`${baseURL}/api/v1/db/storage/upload`, formData, {
headers: uploadHeaders,
});
// Create a new row in the database
const response = await axios.post(`${baseURL}/api/v2/tables/${tableID}/records`, {
// Example field data
"Title": "New Name",
// Pass the uploaded file data; file is field name here & its type is "Attachment"
"file": uploadResponse.data,
}, {
headers: {
'xc-token': apiToken,
'Content-Type': 'application/json',
},
});
})().catch(err => {
console.log(err);
});
Bash
#!/bin/bash
# Required configuration
API_TOKEN="YOUR_API_TOKEN"
BASE_URL="https://app.nocodb.com"
TABLE_ID="YOUR_TABLE_ID" # e.g., m7wp2q8n4d9w4kp
FILE_PATH="./upload/photo.png" # Path to file to upload
FIELD_NAME="File" # Name of attachment field
TITLE_FIELD="Title" # Optional: a text field
TITLE_VALUE="New Name" # Optional: text value
# Step 1: Upload the file
echo "Uploading file..."
UPLOAD_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/v1/db/storage/upload" \
-H "xc-token: ${API_TOKEN}" \
-F "file=@${FILE_PATH}")
echo "Upload response: $UPLOAD_RESPONSE"
# Step 2: Create the record with uploaded file
echo "Creating record..."
CREATE_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/v2/tables/${TABLE_ID}/records" \
-H "xc-token: ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"${TITLE_FIELD}\": \"${TITLE_VALUE}\",
\"${FIELD_NAME}\": ${UPLOAD_RESPONSE}
}")
echo "Create response: $CREATE_RESPONSE"
📝 Instructions
- Save the file as
upload-and-insert.sh
- Make it executable:
chmod +x upload-and-insert.sh
- Update the following variables:
API_TOKEN
TABLE_ID
FILE_PATH
- Field names (
file
,Title
, etc.)
- Run the script:
./upload-and-insert.sh
Typescript
import axios from 'axios';
import FormData from 'form-data';
import fs from 'fs';
import path from 'path';
const uploadAndInsert = async (): Promise<void> => {
const apiToken = 'YOUR_API_TOKEN'; // Replace with your actual API token
const baseURL = 'https://app.nocodb.com';
const tableID = 'YOUR_TABLE_ID'; // Replace with your actual table ID
const filePath = path.resolve('../uploads/photo.png');
const photoStream = fs.createReadStream(filePath);
const formData = new FormData();
formData.append('file', photoStream);
const uploadHeaders = {
'xc-token': apiToken,
...formData.getHeaders(),
};
try {
const uploadResponse = await axios.post(`${baseURL}/api/v1/db/storage/upload`, formData, {
headers: uploadHeaders,
});
const uploadedFileData = uploadResponse.data;
const recordResponse = await axios.post(`${baseURL}/api/v2/tables/${tableID}/records`, {
Title: 'New Name',
file: uploadedFileData,
}, {
headers: {
'xc-token': apiToken,
'Content-Type': 'application/json',
},
});
console.log('Record created:', recordResponse.data);
} catch (error) {
console.error('Error occurred:', error);
}
};
// Invoke properly
(async () => {
await uploadAndInsert();
})();
📝 Instructions
Install required packages:
npm install axios form-data @types/form-data
If using Node.js with TypeScript, also install:
npm install --save-dev @types/node
- Make sure your TypeScript
tsconfig.json
includes"esModuleInterop": true
to support default imports from CommonJS libraries likeaxios
,form-data
, andfs
.
Python
import requests
# Configuration
API_TOKEN = "YOUR_API_TOKEN"
BASE_URL = "https://app.nocodb.com"
TABLE_ID = "YOUR_TABLE_ID"
FILE_PATH = "./photo.png"
# Step 1: Upload the file
with open(FILE_PATH, 'rb') as file:
files = {
'file': file
}
headers = {
'xc-token': API_TOKEN
}
print("Uploading file...")
upload_response = requests.post(
f"{BASE_URL}/api/v1/db/storage/upload",
headers=headers,
files=files
)
if upload_response.status_code != 200:
print("Upload failed:", upload_response.text)
exit(1)
uploaded_file_data = upload_response.json()
print("Upload response:", uploaded_file_data)
# Step 2: Insert a new record with uploaded file
record_payload = {
"Title": "New Name", # adjust field names as needed
"File": uploaded_file_data # must match the name of your attachment field
}
headers = {
'xc-token': API_TOKEN,
'Content-Type': 'application/json'
}
print("Creating record...")
record_response = requests.post(
f"{BASE_URL}/api/v2/tables/{TABLE_ID}/records",
headers=headers,
json=record_payload
)
if record_response.status_code != 200:
print("Record creation failed:", record_response.text)
else:
print("Record created:", record_response.json())
📝 Instructions
Make sure you have requests
installed:
pip install requests
Ruby
require 'net/http'
require 'uri'
require 'json'
require 'mime/types'
# Configuration
API_TOKEN = 'YOUR_API_TOKEN'
BASE_URL = 'https://app.nocodb.com'
TABLE_ID = 'YOUR_TABLE_ID'
FILE_PATH = './photo.png'
# Step 1: Upload the file
uri = URI("#{BASE_URL}/api/v1/db/storage/upload")
file = File.open(FILE_PATH)
mime_type = MIME::Types.type_for(FILE_PATH).first.to_s
request = Net::HTTP::Post::Multipart.new uri.path,
'file' => UploadIO.new(file, mime_type, File.basename(file))
request['xc-token'] = API_TOKEN
puts "Uploading file..."
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.request(request)
if response.code.to_i != 200
puts "Upload failed: #{response.body}"
exit(1)
end
uploaded_file_data = JSON.parse(response.body)
puts "Upload response: #{uploaded_file_data}"
# Step 2: Insert a record
uri = URI("#{BASE_URL}/api/v2/tables/#{TABLE_ID}/records")
payload = {
"Title" => "New Name",
"file" => uploaded_file_data
}.to_json
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['xc-token'] = API_TOKEN
request.body = payload
puts "Creating record..."
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
if response.code.to_i != 200
puts "Record creation failed: #{response.body}"
else
puts "Record created: #{response.body}"
end
📝 Instructions
You’ll need the multipart-post
and mime-types
gems:
gem install multipart-post mime-types
Add at the top if needed:
require 'net/http/post/multipart'
JAVA
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class NocoDBUploaderOkHttp {
private static final String API_TOKEN = "YOUR_API_TOKEN";
private static final String BASE_URL = "https://app.nocodb.com";
private static final String TABLE_ID = "YOUR_TABLE_ID";
private static final String FILE_PATH = "./photo.png";
public static void main(String[] args) throws IOException {
OkHttpClient client = new OkHttpClient();
ObjectMapper mapper = new ObjectMapper();
// Step 1: Upload file
File file = new File(FILE_PATH);
String mimeType = okhttp3.internal.http.HttpDate.format(new Date()); // fallback if type is unknown
RequestBody fileBody = RequestBody.create(file, MediaType.parse(Files.probeContentType(file.toPath())));
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), fileBody)
.build();
Request uploadRequest = new Request.Builder()
.url(BASE_URL + "/api/v1/db/storage/upload")
.header("xc-token", API_TOKEN)
.post(multipartBody)
.build();
System.out.println("Uploading file...");
try (Response response = client.newCall(uploadRequest).execute()) {
if (!response.isSuccessful()) {
System.err.println("Upload failed: " + response.body().string());
return;
}
String uploadResponseStr = response.body().string();
System.out.println("Upload response: " + uploadResponseStr);
// Step 2: Create record
List<Object> fileData = mapper.readValue(uploadResponseStr, List.class);
Map<String, Object> record = new HashMap<>();
record.put("Title", "New Name");
record.put("file", fileData); // field name in your NocoDB table
RequestBody recordBody = RequestBody.create(
mapper.writeValueAsString(record),
MediaType.parse("application/json")
);
Request recordRequest = new Request.Builder()
.url(BASE_URL + "/api/v2/tables/" + TABLE_ID + "/records")
.header("xc-token", API_TOKEN)
.header("Content-Type", "application/json")
.post(recordBody)
.build();
System.out.println("Creating record...");
try (Response recordResponse = client.newCall(recordRequest).execute()) {
if (!recordResponse.isSuccessful()) {
System.err.println("Record creation failed: " + recordResponse.body().string());
} else {
System.out.println("Record created: " + recordResponse.body().string());
}
}
}
}
}
Upload local files (batch)
Javascript
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
(async () => {
const apiToken = 'YOUR_API_TOKEN';
const baseURL = 'https://app.nocodb.com';
const tableID = 'YOUR_TABLE_ID';
// List of file paths to upload
const filesToUpload = [
'./uploads/photo.png',
'./uploads/photo2.png',
'./uploads/photo3.png'
];
const uploadedFiles = [];
// Upload each file one by one
for (const filePath of filesToUpload) {
const fileStream = fs.createReadStream(filePath);
const formData = new FormData();
formData.append('file', fileStream);
const uploadHeaders = {
'xc-token': apiToken,
...formData.getHeaders(),
};
try {
const uploadResponse = await axios.post(`${baseURL}/api/v1/db/storage/upload`, formData, {
headers: uploadHeaders,
});
// Add the uploaded file metadata to the array
uploadedFiles.push(...uploadResponse.data); // .data is an array
} catch (err) {
console.error(`Failed to upload file ${filePath}:`, err.response?.data || err.message);
}
}
// Insert the record with all uploaded files
try {
const response = await axios.post(`${baseURL}/api/v2/tables/${tableID}/records`, {
Title: "New Name",
File: uploadedFiles, // Pass multiple files as array
}, {
headers: {
'xc-token': apiToken,
'Content-Type': 'application/json',
},
});
console.log("Record created:", response.data);
} catch (err) {
console.error("Failed to create record:", err.response?.data || err.message);
}
})();