Upload a source file or archive
One file per request, max 2 GiB; archives (.zip, .tar, .tar.gz, .tgz) are expanded by the import runtime. Stages the source without indexing it — curate explicitly before querying.
POST /contexts/{slug}/import/upload
curl --request POST \
--url https://{host}/api/contexts/{slug}/import/upload \
--header 'Authorization: Bearer <token>' \
--header 'X-Pinecone-Api-Version: <x-pinecone-api-version>'import requests
url = "https://{host}/api/contexts/{slug}/import/upload"
headers = {
"Authorization": "Bearer <token>",
"X-Pinecone-Api-Version": "<x-pinecone-api-version>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: "POST", headers: {"Authorization": "Bearer <token>", "X-Pinecone-Api-Version": "<x-pinecone-api-version>"}};
fetch("https://{host}/api/contexts/{slug}/import/upload", 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://{host}/api/contexts/{slug}/import/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"X-Pinecone-Api-Version: <x-pinecone-api-version>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/contexts/{slug}/import/upload"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Pinecone-Api-Version", "<x-pinecone-api-version>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/api/contexts/{slug}/import/upload")
.header("Authorization", "Bearer <token>")
.header("X-Pinecone-Api-Version", "<x-pinecone-api-version>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/contexts/{slug}/import/upload")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-Pinecone-Api-Version"] = '<x-pinecone-api-version>'
response = http.request(request)
puts response.read_body{
"task_id": "<string>",
"state": "<string>",
"exploring": true,
"profiling": true,
"importing": true
}{
"message": "<string>",
"code": "<string>"
}Authorizations
Section titled “Authorizations”AuthorizationstringrequiredSession token from POST /auth/login, sent as Authorization: Bearer <token>.
Headers
Section titled “Headers”X-Pinecone-Api-Version?stringDate-based contract version, echoed back on the same header. Omit for the default (2026-07); send unstable for the in-development surface. An unrecognized value is rejected with 400 unsupported_api_version.
Path Parameters
Section titled “Path Parameters”slugstringrequiredContext slug or UUID.
Query Parameters
Section titled “Query Parameters”path?stringSubdirectory under the source tree
filestringrequiredFile bytes. Archives are expanded by the import runtime.
Response
Section titled “Response”200 — Upload accepted; import enqueued (state: importing)
What every context-workflow trigger returns. The work is asynchronous: poll GET /tasks/{task_id}. The per-workflow booleans duplicate state and appear only where a workflow's contract names one.
task_idstringrequiredThe enqueued task. Poll it at GET /tasks/id.
statestringrequiredThe forward-looking status the trigger put the context into.
exploring?booleanDuplicates state; present only for explore
profiling?booleanDuplicates state; present only for profile
importing?booleanDuplicates state; present only for the import/curate triggers