Skip to main content

Overview

The /api/sync endpoint manages Amazon Bedrock Knowledge Base ingestion jobs. It provides two methods:
  • POST: Start a new ingestion job
  • GET: Check the status of a running ingestion job

POST /api/sync

Start a new Knowledge Base ingestion job. The endpoint creates an execution ID, starts the ingestion process asynchronously, and returns immediately. The job continues running in the background with automatic status polling every 4 seconds.

Request Body

The request must be sent as JSON:
region
string
required
AWS region where your Knowledge Base is located (e.g., us-east-1)
knowledgeBaseId
string
required
The unique identifier of your Bedrock Knowledge Base
dataSourceId
string
required
The unique identifier of the data source within the Knowledge Base
accessKeyId
string
required
AWS Access Key ID for authentication
secretAccessKey
string
required
AWS Secret Access Key for authentication
sessionToken
string
Optional AWS Session Token for temporary credentials
description
string
Optional description for the ingestion job (default: “Sincronización ejecutada desde la interfaz de chat”)

Request Example

{
  "region": "us-east-1",
  "knowledgeBaseId": "ABCDEFGHIJ",
  "dataSourceId": "KLMNOPQRST",
  "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
  "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "description": "Sync documents from workshop"
}

Response

Success (202 Accepted)

executionId
string
A unique UUID for tracking this execution. Use this ID with GET /api/sync to monitor progress.
{
  "executionId": "123e4567-e89b-12d3-a456-426614174000"
}
The 202 status code indicates the job has been accepted and is running asynchronously. The actual ingestion process continues in the background.

Error Responses

400 Bad Request

{
  "error": "Faltan parámetros de sincronización."
}
Returned when required fields are missing.

500 Internal Server Error

{
  "error": "Error message from AWS or internal error"
}

Implementation Details

The endpoint uses an asynchronous background process:
const executionId = crypto.randomUUID();

executions.set(executionId, {
  id: executionId,
  status: 'PENDIENTE',
  logs: [`[${new Date().toLocaleString('es-ES')}] Ejecución creada.`],
  startedAt: new Date().toISOString()
});

void runSyncProcess(executionId, payload);
The background process:
  1. Starts the ingestion job with StartIngestionJobCommand
  2. Polls the job status every 4 seconds with GetIngestionJobCommand
  3. Continues polling while status is STARTING or IN_PROGRESS
  4. Updates execution status to COMPLETADO or FALLIDO when done

cURL Example

curl -X POST https://your-domain.com/api/sync \
  -H "Content-Type: application/json" \
  -d '{
    "region": "us-east-1",
    "knowledgeBaseId": "ABCDEFGHIJ",
    "dataSourceId": "KLMNOPQRST",
    "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "description": "Manual sync from UI"
  }'

JavaScript Example

const response = await fetch('/api/sync', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    region: 'us-east-1',
    knowledgeBaseId: 'ABCDEFGHIJ',
    dataSourceId: 'KLMNOPQRST',
    accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
    secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
    description: 'Sync from dashboard'
  })
});

const data = await response.json();
const executionId = data.executionId;

// Poll for status updates
const checkStatus = async () => {
  const statusResponse = await fetch(`/api/sync?executionId=${executionId}`);
  const execution = await statusResponse.json();
  console.log(`Status: ${execution.status}`);
  
  if (execution.status === 'EN_EJECUCION' || execution.status === 'PENDIENTE') {
    setTimeout(checkStatus, 2000);
  }
};

checkStatus();

GET /api/sync

Retrieve the current status and logs of a running or completed ingestion job.

Request Parameters

executionId
string
required
The execution ID returned by POST /api/sync

Response

Success (200 OK)

id
string
The execution ID
status
string
Current status: PENDIENTE, EN_EJECUCION, COMPLETADO, or FALLIDO
logs
array
Array of log messages with timestamps
startedAt
string
ISO 8601 timestamp when the execution started
finishedAt
string
ISO 8601 timestamp when the execution finished (only present if completed or failed)
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "COMPLETADO",
  "logs": [
    "[3/5/2024, 10:00:00 AM] Ejecución creada.",
    "[3/5/2024, 10:00:01 AM] Iniciando tarea de sincronización en Bedrock Knowledge Base...",
    "[3/5/2024, 10:00:03 AM] Ingestion Job iniciado: abc123xyz",
    "[3/5/2024, 10:00:07 AM] Estado actual: IN_PROGRESS",
    "[3/5/2024, 10:00:11 AM] Estado actual: IN_PROGRESS",
    "[3/5/2024, 10:00:15 AM] Estado actual: COMPLETE",
    "[3/5/2024, 10:00:15 AM] Sincronización completada correctamente."
  ],
  "startedAt": "2024-03-05T15:00:00.000Z",
  "finishedAt": "2024-03-05T15:00:15.000Z"
}

Status Values

StatusDescription
PENDIENTEExecution created, waiting to start
EN_EJECUCIONIngestion job is actively running
COMPLETADOIngestion job completed successfully
FALLIDOIngestion job failed or encountered an error

Error Responses

404 Not Found

{
  "error": "No se encontró la ejecución solicitada."
}
Returned when the execution ID doesn’t exist or has expired from memory.

cURL Example

curl -X GET "https://your-domain.com/api/sync?executionId=123e4567-e89b-12d3-a456-426614174000"

JavaScript Example

const executionId = '123e4567-e89b-12d3-a456-426614174000';

const response = await fetch(`/api/sync?executionId=${executionId}`);
const execution = await response.json();

console.log(`Status: ${execution.status}`);
console.log('Logs:');
execution.logs.forEach(log => console.log(log));

if (execution.finishedAt) {
  const duration = new Date(execution.finishedAt) - new Date(execution.startedAt);
  console.log(`Duration: ${duration / 1000} seconds`);
}

Polling Pattern

The endpoint implements automatic polling with a 4-second interval:
while (currentStatus === 'STARTING' || currentStatus === 'IN_PROGRESS') {
  await wait(4000);

  const statusResponse = await client.send(
    new GetIngestionJobCommand({
      knowledgeBaseId: payload.knowledgeBaseId,
      dataSourceId: payload.dataSourceId,
      ingestionJobId
    })
  );

  currentStatus = statusResponse.ingestionJob?.status;
  addLog(executionId, `Estado actual: ${currentStatus || 'DESCONOCIDO'}`);
}
Execution state is stored in server memory. If the server restarts, execution IDs will be lost. For production, consider using a persistent store like Redis or a database.

Knowledge Base Sync

Learn about the Knowledge Base sync interface

KB Configuration

Configure your Knowledge Base settings

Sync History

Retrieve historical ingestion jobs from AWS

Build docs developers (and LLMs) love