Skip to main content
POST
/
api
/
policies
/
import
/
presigned_url
Get Import Presigned URL
curl --request POST \
  --url https://api.example.com/api/policies/import/presigned_url \
  --header 'Content-Type: application/json' \
  --data '
{
  "filename": "<string>",
  "content_type": "<string>"
}
'
{
  "import_id": "550e8400-e29b-41d4-a716-446655440000",
  "upload_url": "https://example-bucket.s3.amazonaws.com/policy-imports/raw/550e8400-e29b-41d4-a716-446655440000.bin?X-Amz-Algorithm=...",
  "upload_method": "PUT",
  "s3_bucket": "example-bucket",
  "s3_key": "policy-imports/raw/550e8400-e29b-41d4-a716-446655440000.bin",
  "required_headers": {
    "Content-Type": "application/pdf"
  },
  "expires_in_seconds": 900,
  "expires_at": "2026-06-15T10:45:00Z",
  "max_upload_bytes": 1073741824,
  "next_steps": {
    "step_1": "PUT the raw file bytes to upload_url with the exact required_headers",
    "step_2": "POST /api/policies/import/start with { \"import_id\": \"550e8400-...\" } to begin extraction"
  }
}
Step 1 of the large-file custom policy import flow. Returns an import_id and an S3 presigned upload_url so you can upload large policy documents directly to S3, bypassing the API Gateway and Lambda payload limits that cap the inline Import Policy endpoint. After uploading, call Start Import with the import_id to begin rule extraction.
Use the inline Import Policy endpoint for plain text and small files. Use this presigned flow for large files (above a few MB). Maximum upload size is 1 GB.Large documents (e.g. a multi-hundred-page regulatory handbook) are fully extracted — rule extraction runs in the background in chunks, so the entire document is analyzed, not just the first pages. The trade-off is time: a very large document can stay in processing for several minutes. Keep polling Get Import Details until the status leaves processing.

Request Body

filename
string
Original filename, for reference/audit.
content_type
string
default:"application/pdf"
MIME type of the file you will upload. Must match the Content-Type header you send on the PUT.

Response

import_id
string
Unique identifier for the import. Pass this to Start Import after uploading.
upload_url
string
S3 presigned URL for the file upload (HTTP PUT).
upload_method
string
HTTP method to use for upload (always PUT).
s3_bucket
string
S3 bucket name.
s3_key
string
S3 object key the file will be uploaded to.
required_headers
object
Important: Headers that MUST be included on the upload PUT. The presigned URL is signed with these, so omitting any results in a SignatureDoesNotMatch error from S3.
expires_in_seconds
integer
Seconds until the presigned URL expires (default 900).
expires_at
string
ISO 8601 timestamp when the URL expires.
max_upload_bytes
integer
Maximum allowed upload size in bytes, enforced at Start Import.
next_steps
object
Step-by-step instructions for uploading and starting the import.
{
  "import_id": "550e8400-e29b-41d4-a716-446655440000",
  "upload_url": "https://example-bucket.s3.amazonaws.com/policy-imports/raw/550e8400-e29b-41d4-a716-446655440000.bin?X-Amz-Algorithm=...",
  "upload_method": "PUT",
  "s3_bucket": "example-bucket",
  "s3_key": "policy-imports/raw/550e8400-e29b-41d4-a716-446655440000.bin",
  "required_headers": {
    "Content-Type": "application/pdf"
  },
  "expires_in_seconds": 900,
  "expires_at": "2026-06-15T10:45:00Z",
  "max_upload_bytes": 1073741824,
  "next_steps": {
    "step_1": "PUT the raw file bytes to upload_url with the exact required_headers",
    "step_2": "POST /api/policies/import/start with { \"import_id\": \"550e8400-...\" } to begin extraction"
  }
}
Required headers: Include all headers from required_headers exactly as provided when uploading your file. Missing or mismatched headers (including Content-Type) can cause S3 to reject the upload with SignatureDoesNotMatch.

Example

# Step 1: Get the presigned URL
RESPONSE=$(curl -s -X POST "https://{api-url}/api/policies/import/presigned_url" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "compliance-policy.pdf",
    "content_type": "application/pdf"
  }')

IMPORT_ID=$(printf '%s' "$RESPONSE" | jq -r '.import_id')
UPLOAD_URL=$(printf '%s' "$RESPONSE" | jq -r '.upload_url')

# Build curl -H args from required_headers
CURL_HEADERS=()
while IFS=$'\t' read -r key value; do
  CURL_HEADERS+=(-H "$key: $value")
done < <(printf '%s' "$RESPONSE" | jq -r '.required_headers | to_entries[] | "\(.key)\t\(.value)"')

# Step 2: Upload the raw file directly to S3 (no API key)
curl -X PUT "$UPLOAD_URL" \
  "${CURL_HEADERS[@]}" \
  --data-binary @compliance-policy.pdf

echo "Import ID: $IMPORT_ID"
# Step 3: call POST /api/policies/import/start with this import_id