Jenova - AI 에이전트 플랫폼API 플랫폼

Jenova 에이전트 API 참조

기본 URL: https://api.jenova.ai/v1

인증: Authorization 헤더에 Bearer 토큰 사용


목차


개요

몇 분 만에 맞춤형 에이전트를 제품이나 워크플로에서 실행하세요. 어떤 작업에든 맞게 에이전트를 설정하고, 모델과 도구는 자유롭게 선택하세요. 에이전트 하네스, 데이터베이스, 확장은 Jenova가 처리합니다.

완전한 에이전트 스택:

  • 관리형 에이전트 하네스: 호출은 한 번, 결과물은 완성됩니다. 에이전트가 조사하고 추론하고 도구를 호출하며 파일까지 생성합니다 — 지시하는 대로 정확히 수행합니다.
  • 무한한 컨텍스트와 메모리: RAG 기반 컨텍스트 관리와 독자적인 세션 상태 추적이 하나의 대화 안에서 무제한 메모리를 가능하게 합니다.
  • 도구와 MCP 라이브러리: 검색, 이미지 생성, 이메일 등 30개 이상의 도구와 MCP 서버로 구성된 라이브러리에 연결하거나, 자체 MCP 서버를 직접 연결할 수도 있습니다.
  • 어떤 모델로든 매끄럽게 전환: OpenAI, Anthropic, Google, xAI 또는 주요 오픈소스 제공업체의 모델을 배포하고, 파라미터 하나만 바꿔 모델 간에 전환할 수 있습니다.
  • 관리형 지식과 RAG: Jenova가 엔드투엔드 RAG 파이프라인을 처리합니다 — 청킹, 인덱싱, 저장, 검색까지.
  • 대규모 운영에서 검증됨: 수백 개의 에이전트가 실제 프로덕션에서 운영되는 실전 검증된 인프라 위에 배포하세요. 프로비저닝, 확장, 유지 관리할 클러스터가 전혀 없습니다.

빠른 시작

1. API 키 받기

www.jenova.ai/platform의 개발자 대시보드에서 API 키를 생성합니다. 키는 jnv_sk_* 형식을 사용하며 Bearer 토큰으로 전달됩니다.

2. 에이전트 선택 또는 생성

플랫폼에서 사전 구축된 에이전트를 선택하거나, 대시보드에서 지침, 모델 설정, 지식 베이스 파일, 도구, MCP 서버를 지정하여 커스텀 에이전트를 생성합니다.

3. 첫 메시지 보내기

세션을 생성하고 한 번의 호출로 메시지를 보냅니다:

curl -N -X POST https://api.jenova.ai/v1/messages \
  -H "Authorization: Bearer jnv_sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "my-support-agent",
    "user": "user_12345",
    "content": "What can you help me with?"
  }'

응답은 Server-Sent Events로 스트리밍되어 돌아옵니다:

event: stream_started
data: {"session_id":"ses_xyz789","run_id":"run_abc123","agent":"my-support-agent"}

event: stream_delta
data: {"session_id":"ses_xyz789","run_id":"run_abc123","chunk_content":"I can help you with ","seq":1}

event: stream_ended
data: {"session_id":"ses_xyz789","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}

후속 요청을 위해 stream_started에서 session_id를 확보하세요. 동기식 JSON 응답에 대해서는 메시지 보내기를 참조하세요.


핵심 개념

에이전트

API를 통해 상호작용하는 AI 에이전트입니다. 각 에이전트는 API 호출에서 agent 값으로 사용되는 고유한 slug(예: my-support-agent)를 가집니다.

  • 사전 구축: 플랫폼에 있는 기존 에이전트 중에서 선택합니다.
  • 커스텀: 대시보드에서 지침, 모델, 지식 베이스, 도구, MCP 서버를 지정하여 직접 구성합니다.

세션

최종 사용자와 에이전트 간의 독립적인 대화 스레드입니다.

  • 식별자: 접두사가 붙은 ID(예: ses_abc123).
  • 범위: 동일한 에이전트와 최종 사용자에 대해 여러 세션이 존재할 수 있으며, 각 세션은 독립적인 대화 상태를 가집니다.
  • 수명 주기: 세션은 API를 통해 삭제되기 전까지 무기한 유지됩니다. 세션이 필요 없는 일회성 작업의 경우 ephemeral: true와 함께 POST /messages를 사용하세요.
  • 플랫폼 분리: API 세션은 Jenova 웹 앱의 대화와 별개입니다. 최종 사용자, 세션 기록, 결제는 API와 웹 앱 간에 독립적으로 관리됩니다.

메시지

메시지 API 엔드포인트가 반환하는 세션 대화 기록의 단일 항목입니다. 각 메시지에는 type(user 또는 agent)과 name을 포함하는 구조화된 from 객체와, 메시지 자체의 type이 포함됩니다:

  • external - 채팅 콘텐츠로 표시되도록 의도된 대화 메시지입니다.
  • internal - 실행 중 도구 호출이나 검색과 같은 에이전트 작업 단계를 나타내는 선택적 메시지입니다.

실행

메시지를 보낼 때 생성되는 단일 에이전트 실행입니다. 실행에는 run_id가 있으며, 활성 상태 동안 이벤트를 스트리밍할 수 있고, 하나 이상의 완료된 메시지를 생성할 수 있습니다. 각 세션은 한 번에 하나의 활성 실행만 가질 수 있습니다.

최종 사용자

user 필드는 세션을 귀하의 애플리케이션 내 최종 사용자 범위로 지정합니다. 내부 사용자 ID나 UUID와 같은 안정적이고 불투명한 ID를 사용하세요. 애플리케이션에서 필요하지 않은 경우 이메일이나 기타 개인식별정보(PII)는 피하세요. 동일한 user 값으로 생성된 세션은 함께 그룹화되어 사용자별 세션 목록 조회가 가능해집니다.

user가 생략되면 세션은 귀하의 개발자 계정 범위로 지정되며, 이후 최종 사용자별로 필터링할 수 없습니다. 프로덕션에서는 user를 전달하세요.

기존 세션에 대한 요청(경로에 {session_id}가 포함된 모든 엔드포인트)의 경우 user는 선택적인 소유권 확인 용도로 사용됩니다. 값을 제공하는 경우, 세션 생성 시 사용된 user 값과 일치해야 합니다. 그렇지 않으면 API는 404 session_not_owned를 반환합니다. GET 및 DELETE 요청에서는 쿼리 파라미터로, POST 및 PATCH 요청에서는 JSON 본문에 담아 전달하세요. POST 또는 PATCH에서 user를 쿼리 파라미터로 전달하면 400 bad_request가 반환됩니다.


인증

모든 요청은 Authorization 헤더에 Bearer 토큰을 포함하여 인증해야 합니다:

Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

API 키는 개발자 대시보드에서 생성됩니다.

User-Agent는 선택 사항입니다. SDK는 진단 목적으로 이 값을 설정할 수 있지만, API에서 필수로 요구하지는 않습니다.

키 형식: 키는 접두사 jnv_sk_로 시작하며 그 뒤에 base62로 인코딩된 무작위 문자열이 이어집니다.

제한: 개발자 계정당 최대 10개의 활성 API 키를 가질 수 있습니다.


API 엔드포인트

메시지 API

메시지 보내기는 주요 API 경로입니다. 첫 메시지에는 POST /messages를 사용하며, 이 요청은 하나의 요청으로 세션을 생성하고 실행을 시작합니다. 캡처된 session_id로 계속하는 경우에는 POST /sessions/{session_id}/messages를 사용합니다.

메시지 보내기

POST /messages

하나의 요청으로 영구 세션을 생성하고 첫 메시지를 보냅니다. 스트리밍 단발성 요청을 원한다면 ephemeral: true를 설정합니다. 이 경우 세션 ID가 반환되지 않고 이어서 계속할 수 없습니다. 데이터는 요청이 완료된 직후 삭제됩니다.

요청 본문

필드유형필수기본값설명
agentstring필수-에이전트의 슬러그 식별자
contentstring조건부-메시지 텍스트. file_urls가 제공되지 않는 경우 필수
file_urlsstring[]조건부-첨부할 파일의 URL. content가 제공되지 않는 경우 필수
userstring선택-귀하의 외부 최종 사용자 식별자(최대 255자). 생략하면 귀하의 개발자 계정으로 기본 설정됩니다
session_namestring선택-새 세션의 표시 이름(최대 200자)
ephemeralboolean선택false스트리밍 전용 단발성 요청입니다. 세션 ID가 반환되지 않고, 이어서 계속할 수 없으며, 데이터는 요청이 완료된 직후 삭제됩니다
streamboolean선택trueSSE 스트리밍의 경우 true, JSON의 경우 false. MCP 인가에는 스트리밍이 필요합니다
include_progressboolean선택truestream_progress 이벤트를 생략하려면 false로 설정합니다. 스트리밍 전용
modelstring선택-이 요청에 한해 일회성으로 모델을 재지정합니다. claude-sonnet-5와 같은 안정적인 모델 ID를 사용하십시오. 세션의 기본 모델은 변경되지 않습니다
additional_contextobject[]선택-이 요청에만 적용되는 이름 지정 컨텍스트입니다. 추가 컨텍스트 참조

예시 - 스트리밍(기본값)

curl -N -X POST https://api.jenova.ai/v1/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "my-support-agent",
    "user": "user_12345",
    "content": "Hello, I need help with my account"
  }'

응답은 SSE 스트림입니다(이벤트 형식은 스트리밍 (SSE) 참조). 영구 요청에는 새로운 session_id가 포함되며, ephemeral: true 요청에는 session_id가 포함되지 않고 반드시 스트리밍을 사용해야 합니다.

예시 - JSON(비스트리밍)

curl -X POST https://api.jenova.ai/v1/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "my-support-agent",
    "user": "user_12345",
    "content": "Hello, I need help with my account",
    "stream": false
  }'

응답

스트리밍 응답은 스트리밍 (SSE)에 문서화된 SSE 이벤트를 발생시킵니다. 비스트리밍 응답은 세션 계속하기에 표시된 것처럼 요청에 대한 stop_reason과 usage를 포함한 메시지 객체를 반환합니다. stop_reason은 end_run이며, 에이전트가 메시지를 생성한 후 실행이 취소된 경우에는 user_cancelled입니다.

에이전트가 메시지를 생성하기 전에 실행이 취소되면 API는 status: "cancelled", session_id, run_id, stop_reason: "user_cancelled", usage와 함께 200 OK를 반환합니다.

비스트리밍 실행이 90초가 지나도 여전히 처리 중인 경우, API는 status: "processing", session_id, run_id, 사람이 읽을 수 있는 message와 함께 202 Accepted를 반환합니다. 실행은 응답이 반환되거나 클라이언트 연결이 끊긴 후에도 계속되므로, 세션의 메시지를 확인하거나 더 긴 워크플로에는 스트리밍을 사용하십시오.

오류

상태코드조건
400missing_required_fieldagent는 필수입니다
400invalid_payload잘못된 형식의 JSON이거나 필드의 유형이 유효하지 않습니다
400bad_request유효하지 않은 ephemeral 모드 또는 additional_context이거나, user/session_name이 최대 길이를 초과했습니다
400content_or_uploaded_files_requiredcontent와 file_urls 중 어느 것도 제공되지 않았습니다
400content_too_long메시지 내용이 32,000 토큰을 초과했습니다
400exceed_max_upload_files하나의 요청에 서로 다른 파일 URL이 10개를 초과하여 포함되었습니다
400unsupported_file_format파일 URL의 확장자가 지원되지 않습니다
400invalid_file_url파일 URL의 형식이 올바르지 않거나 HTTPS가 아닙니다
400invalid_model_selectionmodel이 유효한 모델 ID가 아니거나, 에이전트의 기본 모델을 사용할 수 없습니다
402insufficient_credits세션을 생성하거나 메시지를 보내기에 크레딧이 충분하지 않습니다
404agent_not_found에이전트가 존재하지 않거나 귀하의 계정에서 접근할 수 없습니다

세션 계속하기

POST /sessions/{session_id}/messages

기존 영속 세션에 메시지를 전송하고 에이전트의 응답을 받습니다. 응답은 기본적으로 SSE를 통해 스트리밍되며, JSON으로 받으려면 stream: false로 설정하세요.

요청 본문

필드유형필수기본값설명
contentstring조건부-메시지 텍스트. file_urls가 제공되지 않는 경우 필수
file_urlsstring[]조건부-첨부할 파일의 URL. content가 제공되지 않는 경우 필수
streamboolean아니오trueSSE 스트리밍의 경우 true, JSON의 경우 false. MCP 인증에는 스트리밍이 필요함
include_progressboolean아니오truestream_progress 이벤트를 생략하려면 false로 설정합니다. 스트리밍 전용
modelstring아니오-이 요청에 한해 일회성으로 모델을 재정의합니다. claude-sonnet-5와 같은 안정적인 모델 ID를 사용하세요. 세션의 기본 모델은 변경되지 않습니다
additional_contextobject[]선택-이 요청에만 적용되는 이름 지정 컨텍스트입니다. 추가 컨텍스트 참조

예시 - 스트리밍(기본값)

curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "How do I reset my password?"
  }'

예시 - JSON(비스트리밍)

curl -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "How do I reset my password?",
    "stream": false
  }'

응답 200 OK

{
  "id": "msg_xyz789",
  "session_id": "ses_abc123",
  "sequence": 4,
  "from": {
    "type": "agent",
    "name": "my-support-agent"
  },
  "type": "external",
  "time": "2026-05-19T10:31:05Z",
  "content": "To reset your password, go to Settings > Security > Change Password...",
  "model": "claude-sonnet-5",
  "files": [],
  "stop_reason": "end_run",
  "usage": {
    "cost": "0.0015"
  }
}

세션에 이미 활성 실행이 있거나 대기 중인 메시지가 있는 경우, API는 status: "queued", session_id, run_id, message_id와 함께 JSON 202 Accepted를 반환합니다. 사용자 메시지는 해당 활성 실행에 의해 처리됩니다. additional_context가 포함된 요청은 대신 409 busy를 반환합니다.

비스트리밍 응답은 에이전트가 메시지를 생성하기 전에 실행이 취소된 경우의 status: "cancelled" 응답을 포함하여 메시지 보내기와 동일한 규칙을 따릅니다.

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 유효하지 않음
400bad_request유효하지 않은 additional_context
400content_or_uploaded_files_requiredcontent와 file_urls 중 어느 것도 제공되지 않음
400content_too_long메시지 콘텐츠가 32,000 토큰을 초과함
400exceed_max_upload_files단일 요청에 서로 다른 파일 URL이 10개를 초과하여 포함됨
400unsupported_file_format파일 URL에 지원되지 않는 파일 확장자가 사용됨
400invalid_file_url파일 URL 형식이 잘못되었거나 HTTPS가 아님
400invalid_model_selectionmodel이 유효한 모델 ID가 아니거나, 세션의 모델을 더 이상 사용할 수 없음
402insufficient_credits메시지를 전송하기에 크레딧이 부족함
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 지정된 user와 일치하지 않음
409busy다른 업데이트가 진행 중이어서 세션을 일시적으로 사용할 수 없거나, 세션에 활성 실행이나 대기 중인 메시지가 있는 동안 additional_context가 전송됨
429too_many_pending세션에 이미 대기 중인 메시지가 200개 있음
503service_unavailable서비스를 일시적으로 사용할 수 없음

멱등성

POST /messages, POST /sessions/{session_id}/messages, POST /invoke는 선택적으로 Idempotency-Key 헤더(최대 255자)를 허용합니다. 네트워크 재시도나 중복 제출로 인해 중복된 실행이 생성되지 않도록, 논리적인 사용자 전송마다 고유한 키를 사용하십시오. 키는 24시간 동안 보관됩니다.

curl -N -X POST https://api.jenova.ai/v1/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: send-user_12345-2026-05-19T10:30:00Z" \
  -d '{
    "agent": "my-support-agent",
    "user": "user_12345",
    "content": "Hello"
  }'

비스트리밍: 재시도하면 Idempotent-Replayed: true 헤더와 함께 저장된 응답이 반환되며, 요청 처리가 시작된 후 반환된 오류도 포함됩니다. 저장된 202 Accepted 응답은 그대로 다시 반환되므로, 결과를 확인하려면 실행 상태 조회 또는 메시지 목록 조회를 사용하십시오. 유효성 검사 오류나 크레딧 오류처럼 처리가 시작되기 전에 거부된 요청은 저장되지 않으므로, 재시도하면 다시 평가됩니다.

스트리밍: 스트림은 재생되지 않습니다. POST /messages 및 POST /sessions/{session_id}/messages의 경우, 실행 중이거나 완료된 후에 재시도하면 원본 run_id와, 영속적인 요청의 경우 session_id가 포함된 멱등성 오류가 반환됩니다. 영속적인 요청의 경우 활성 실행을 확인하려면 실행 상태 조회를 사용하고, 저장된 결과를 가져오려면 메시지 목록 조회를 사용하십시오. 스트리밍된 POST /invoke 결과는 스트림이 닫힌 후에는 가져올 수 없습니다. POST /invoke 재시도는 run_id와 session_id 대신 원래 id를 반환합니다.

완료된 스트리밍 재시도 예시:

HTTP/1.1 409 Conflict
Content-Type: application/json
{
  "error": {
    "code": "idempotency_key_reused",
    "message": "This Idempotency-Key has already completed. Streaming responses cannot be replayed; use the returned session_id and run_id to retrieve the result."
  },
  "idempotency": {
    "status": "completed",
    "session_id": "ses_abc123",
    "run_id": "run_abc123"
  }
}

멱등성 오류

상태 코드코드조건
400bad_requestIdempotency-Key가 최대 길이를 초과함
409idempotency_key_reused동일한 키가 다른 요청과 함께 사용됨
409idempotency_key_in_use원본 요청이 아직 실행 중임
409idempotency_key_reused원본 스트리밍 요청이 이미 완료되어 재생할 수 없음

메시지 목록 조회

GET /sessions/{session_id}/messages

세션 메시지의 페이지네이션된 목록을 반환합니다. 기본적으로 external 대화 메시지만 반환됩니다. 첫 번째 페이지에는 가장 최근 메시지가 포함되며, 각 페이지 내에서 메시지는 시간순(오래된 것부터)으로 정렬됩니다. sequence는 세션 내에서 메시지의 정렬 번호입니다.

쿼리 파라미터

파라미터유형기본값최대값설명
limitinteger20100페이지당 메시지 수
cursorstring--페이지네이션 커서
includestringexternal-반환할 메시지 유형: external, internal 또는 all

예시

curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
  -H "Authorization: Bearer jnv_sk_xxx"

응답 200 OK

{
  "items": [
    {
      "id": "msg_002",
      "session_id": "ses_abc123",
      "sequence": 4,
      "from": {
        "type": "agent",
        "name": "my-support-agent"
      },
      "type": "external",
      "time": "2026-05-19T10:31:05Z",
      "content": "To reset your password, go to Settings > Security...",
      "model": "claude-sonnet-5",
      "stop_reason": "end_run"
    }
  ],
  "next_cursor": "",
  "has_more": false
}

메시지 객체

필드유형설명
idstring메시지 ID(msg_ 접두사)
session_idstring상위 세션 ID
sequenceinteger세션 내 정렬 번호. 메시지가 삭제된 후 번호가 재사용될 수 있음
fromobject발신자 객체로, type(user 또는 agent)과 name을 포함
typestring대화 메시지의 경우 external, 에이전트 작업 단계의 경우 internal
timestringISO 8601 타임스탬프
contentstring텍스트 콘텐츠. 외부(external) 메시지에 존재
modelstring응답을 생성한 안정적인 모델 ID. 에이전트 메시지에만 존재
filesarray메시지에 포함된 첨부 또는 생성된 파일. 아래 파일 객체 참고. 메시지에 파일이 없으면 메시지 목록 조회 및 메시지 조회 응답에서 생략됨
stop_reasonstring콘텐츠가 있는 외부(external) 에이전트 메시지에 존재. 값은 end_run
agentstring실행 중인 에이전트 슬러그(가능한 경우)
agent_namestring실행 중인 에이전트 표시 이름(가능한 경우)
progress_eventsarray내부 메시지에 대해 기록된 활동(가능한 경우). 각 항목은 stream_progress 이벤트와 동일한 필드를 가짐

파일 객체

필드유형설명
file_idstringJenova 파일 ID. 알 수 없는 경우 빈 값
namestring파일 이름
urlstring파일 URL. 알 수 없는 경우 빈 값
formatstring소문자 파일 형식(예: pdf, png, csv)
sizeinteger파일 크기(바이트 단위). 알 수 없는 경우 0

오류

상태코드조건
400bad_request잘못된 쿼리 파라미터
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 지정된 user와 일치하지 않음

메시지 조회

GET /sessions/{session_id}/messages/{message_id}

ID로 단일 메시지를 조회합니다.

쿼리 파라미터

파라미터유형기본값설명
includestringexternal반환될 수 있는 메시지 유형: external, internal 또는 all

응답 200 OK

목록 응답과 동일한 구조의 단일 메시지 객체를 반환합니다.

오류

상태코드조건
400bad_request잘못된 쿼리 파라미터
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 지정된 user와 일치하지 않음
404not_found해당 세션에 메시지가 존재하지 않음

파일 첨부

file_urls 필드에 공개적으로 접근 가능한 HTTPS URL을 전달하십시오.

제한값
메시지당 최대 파일 수10
최대 파일 크기파일당 20MB

지원 형식

  • 이미지: JPG, JPEG, PNG, WebP
  • 문서: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
  • 코드: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML

파일 URL은 요청이 수락될 때가 아니라 실행 중 에이전트가 파일을 읽을 때 가져옵니다. 가져올 수 없는 URL이나 20MB를 초과하는 파일은 읽히지 않지만, 요청 자체는 거부되지 않습니다.

메시지를 조회할 때 첨부된 파일은 메시지의 files 배열에 나타납니다.


추가 컨텍스트

최종 사용자의 계정 정보처럼 메시지 하나에만 적용되는 이름 지정 컨텍스트를 additional_context로 전달합니다. 메시지 기록에 저장되지 않습니다.

필드유형필수설명
namestring예영문 소문자, 숫자, 밑줄로 구성되며 영문자로 시작해야 합니다(최대 64자). 밑줄과 복수형 차이를 무시하고 요청 내에서 고유해야 합니다
contentstring예컨텍스트 텍스트. 비어 있으면 안 됩니다(최대 12,000 토큰)
제한값
메시지당 최대 항목 수4
항목당 최대 토큰 수12,000

customer_profile이나 order_details처럼 설명적인 이름을 사용하세요.

name 또는 content가 없거나 문자열이 아닌 항목은 400 invalid_payload를 반환합니다. 그 밖의 잘못된 항목은 400 bad_request를 반환합니다.

curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "How do I reset my password?",
    "additional_context": [
      {
        "name": "customer_profile",
        "content": "Plan: Pro. Last login: 2026-05-18."
      }
    ]
  }'

세션 API

세션은 최종 사용자와 에이전트 간의 지속적인 대화입니다. 대부분의 통합에서는 POST /messages를 사용하여 암묵적으로 세션을 생성할 수 있습니다.

세션 생성

POST /sessions

특정 에이전트에 연결된 비어 있는 영구 세션을 생성합니다. 첫 번째 메시지 이전에 세션 ID가 필요한 경우 사용합니다. 그렇지 않은 경우에는 POST /messages를 사용하는 것이 좋습니다.

참고: POST /sessions에서는 ephemeral을 사용할 수 없습니다. 단발성 요청에는 ephemeral: true와 함께 POST /messages를 사용하세요.

요청 본문

필드유형필수설명
agentstring예에이전트의 slug 식별자
userstring아니오귀하의 외부 최종 사용자 식별자(최대 255자). 생략하면 귀하의 개발자 계정으로 기본 설정됩니다
session_namestring아니오세션의 표시 이름(최대 200자)

예시

curl -X POST https://api.jenova.ai/v1/sessions \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "my-support-agent",
    "user": "user_12345",
    "session_name": "Billing inquiry"
  }'

응답 201 Created

{
  "id": "ses_abc123",
  "session_name": "Billing inquiry",
  "agent": "my-support-agent",
  "user": "user_12345",
  "model": "claude-sonnet-5",
  "created_at": "2026-05-19T10:30:00Z",
  "updated_at": "2026-05-19T10:30:00Z"
}

세션 객체

필드유형설명
idstring세션 ID(ses_ 접두사)
session_namestring표시 이름
agentstring에이전트 slug
agent_detailsobjectdisplay_name을 포함한 에이전트 세부 정보. include=agent로 요청한 경우에만 포함됨
userstring최종 사용자 식별자. user 없이 생성된 세션의 경우 null
modelstring메시지에서 모델을 지정하지 않을 때 사용되는 모델. 세션 생성 시 에이전트의 기본 모델로 설정됨. 에이전트가 Jenova에 모델 선택을 맡기는 경우 비어 있음
created_atstringISO 8601 타임스탬프
updated_atstringISO 8601 타임스탬프

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400missing_required_fieldagent는 필수입니다
400bad_requestephemeral이 전달되었거나, user/session_name이 최대 길이를 초과함
402insufficient_credits세션을 생성할 크레딧이 부족함
404agent_not_found에이전트가 존재하지 않거나 귀하의 계정에서 접근할 수 없음

세션 목록 조회

GET /sessions

귀하의 세션 목록을 최근 업데이트순으로 페이지네이션하여 반환합니다.

쿼리 파라미터

파라미터유형기본값최대값설명
limitinteger20100페이지당 항목 수
cursorstring--페이지네이션 커서
userstring--최종 사용자 식별자로 필터링(최대 255자)
agentstring--에이전트 slug로 필터링
includestring--각 세션에 agent_details를 추가하려면 agent로 설정

예시

curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
  -H "Authorization: Bearer jnv_sk_xxx"

응답 200 OK

{
  "items": [
    {
      "id": "ses_abc123",
      "session_name": "Billing inquiry",
      "agent": "my-support-agent",
      "user": "user_12345",
      "model": "claude-sonnet-5",
      "created_at": "2026-05-19T10:30:00Z",
      "updated_at": "2026-05-19T11:15:00Z"
    }
  ],
  "next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
  "has_more": true
}

오류

상태코드조건
400bad_request유효하지 않은 쿼리 파라미터

세션 조회

GET /sessions/{session_id}

ID로 단일 세션을 조회합니다.

쿼리 파라미터

파라미터유형설명
includestring세션에 agent_details를 추가하려면 agent로 설정

응답 200 OK

세션 객체를 반환합니다.

오류

상태코드조건
400bad_request잘못된 쿼리 파라미터
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 전달된 user와 일치하지 않음

세션 이름 변경

PATCH /sessions/{session_id}

세션의 표시 이름을 업데이트합니다.

요청 본문

필드유형필수설명
session_namestringYes새 표시 이름(최대 200자)

응답 200 OK

업데이트된 세션 객체를 반환합니다.

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400missing_required_fieldsession_name이 필요함
400bad_requestsession_name이 최대 길이를 초과함
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 제공된 user와 일치하지 않음
409busy다른 업데이트가 진행 중이어서 세션을 일시적으로 사용할 수 없음

세션 삭제

DELETE /sessions/{session_id}

세션과 해당 세션의 모든 메시지를 영구적으로 삭제합니다. 세션에 활성 실행이 없어야 합니다.

응답 204 No Content

오류

상태코드조건
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 제공된 user와 일치하지 않음
409busy세션에 활성 실행이 있음 - 먼저 취소하십시오

작업

이 엔드포인트들은 영속 세션에 대한 복구 및 편집 제어 기능입니다. 대부분의 통합은 활성 실행 취소만 필요하며, 세션 상태를 의도적으로 변경하거나 복구하고자 할 때만 다른 작업을 사용하십시오. 모든 작업은 최종 사용자에서 설명된 선택적 user 소유권 보호 기능을 지원합니다.

활성 실행 취소

POST /sessions/{session_id}/cancel

활성 에이전트 실행을 취소합니다. 취소 이전에 이미 완료된 메시지는 삭제되지 않습니다.

요청 본문

필드유형필수설명
run_idstringNo선택적 오래된 실행(stale-run) 보호 기능입니다. 제공되었으나 활성 실행과 일치하지 않으면 API는 409 stale_run을 반환합니다

응답 204 No Content

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400cancel_not_allowed취소할 활성 실행이 없거나 취소가 허용되지 않음
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 제공된 user와 일치하지 않음
409stale_run제공된 run_id가 활성 실행과 일치하지 않음

활성 실행 되돌리기

POST /sessions/{session_id}/undo

활성 실행을 취소하고 중지될 때까지 대기한 후, 해당 실행이 이미 추가한 메시지를 제거합니다. 되돌리기가 실행된 이후에는 추가 출력이 저장되지 않습니다.

요청 본문

필드유형필수설명
run_idstringNo선택적 오래된 실행(stale-run) 보호 기능입니다. 제공되었으나 활성 실행과 일치하지 않으면 API는 409 stale_run을 반환합니다

응답 200 OK

{
  "session_id": "ses_abc123",
  "run_id": "run_abc123",
  "deleted": ["msg_002", "msg_001"]
}

메시지가 완료되기 전에 실행이 취소된 경우, deleted는 빈 배열이 됩니다.

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400cancel_not_allowed되돌릴 활성 실행이 없거나 취소가 허용되지 않음
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 제공된 user와 일치하지 않음
409stale_run제공된 run_id가 활성 실행과 일치하지 않음
409busy다른 업데이트가 진행 중이어서 세션을 일시적으로 사용할 수 없음

최근 메시지 삭제

POST /sessions/{session_id}/messages/delete

유휴 상태인 세션에서 internal 메시지를 포함하여 가장 최근 count개의 메시지를 삭제합니다. 이러한 메시지를 확인하려면 메시지 목록 조회에서 include=all을 사용하세요. 세션에 활성 실행이 없어야 합니다.

요청 본문

필드유형필수설명
countintegerYes끝에서부터 삭제할 최근 메시지 수 (0보다 커야 함). 100보다 큰 값은 100으로 처리됨

응답 200 OK

{
  "deleted": ["msg_002", "msg_001"]
}

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400bad_requestcount가 누락, 0 또는 음수인 경우, 또는 삭제할 메시지가 없는 경우
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속해 있거나 제공된 user와 일치하지 않음
409busy세션에 활성 실행이 있음

세션 포크

POST /sessions/{session_id}/fork

원본 세션을 특정 메시지까지 복사하여 새 세션을 생성합니다. 원본 세션에는 활성 실행이 없어야 합니다.

요청 본문 (선택 사항)

필드유형필수설명
message_idstringNo포크 지점 메시지 ID. 생략하면 마지막 메시지에서 포크됩니다

응답 201 Created

세션 생성과 동일한 구조로 새로 생성된 세션 객체를 반환합니다.

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400bad_requestmessage_id가 유효하지 않음
402insufficient_credits세션을 포크하기에 크레딧이 부족함
404not_found이 세션에 message_id가 존재하지 않음
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속해 있거나 제공된 user와 일치하지 않음
409busy원본 세션에 활성 실행이 있음

실행 상태 조회

GET /sessions/{session_id}/runs/{run_id}

활성 실행의 현재 상태를 반환합니다. SSE 연결이 끊어진 후 또는 run_id를 반환한 멱등성 응답 이후에 사용하십시오. 실행이 완료된 후에는 GET /sessions/{session_id}/messages로 결과를 조회하십시오.

응답 200 OK

{
  "session_id": "ses_abc123",
  "run_id": "run_abc123",
  "status": "streaming",
  "started_at": "2026-05-19T10:30:00Z",
  "updated_at": "2026-05-19T10:30:06Z",
  "content": "Partial visible response text so far"
}

status는 에이전트가 작업하는 동안 running이며, 응답 텍스트가 생성되기 시작하면 streaming, 실행이 끝난 직후 잠시 동안은 ended가 됩니다. 응답에는 stream_progress와 동일한 형식으로 최근 활동을 담은 progress_events가 포함될 수도 있습니다. status가 ended이거나 요청이 404 not_found를 반환하면 세션의 메시지를 가져오세요.

오류

상태코드조건
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속해 있거나 제공된 user와 일치하지 않음
404not_found이 세션에 대해 실행이 활성 상태가 아님

크레딧

잔액 조회

GET /credits/balance

귀하의 현재 크레딧 잔액을 반환합니다.

응답 200 OK

{
  "balance": "123.45"
}

에이전트 API

대시보드에서 커스텀 에이전트를 생성하고 편집하십시오. 에이전트 생성 및 편집을 위한 API 지원은 곧 제공될 예정입니다.

예약/백그라운드 워크플로는 현재 API를 통해 지원되지 않습니다. 지원은 곧 제공될 예정입니다.

에이전트 목록 조회

GET /agents

귀하의 계정에서 사용할 수 있는 에이전트를 반환합니다. 세션을 생성하거나 메시지를 보낼 때 agent 값을 사용하세요.

응답 200 OK

{
  "agents": [
    {
      "agent": "jenova",
      "display_name": "Jenova",
      "description": "General-purpose Jenova agent"
    },
    {
      "agent": "my-support-agent",
      "display_name": "Support Agent",
      "description": "Answers customer questions"
    }
  ]
}
필드유형설명
agentstringagent 값으로 전달할 안정적인 에이전트 슬러그
display_namestring사람이 읽기 쉬운 표시 이름
descriptionstring에이전트 설명

모델

모델 목록 조회

GET /models

메시지를 보내거나 POST /invoke를 호출할 때 model 필드에서 사용할 수 있는 모든 모델을 반환합니다.

응답 200 OK

{
  "models": [
    {
      "id": "claude-opus-4-8",
      "name": "Claude Opus 4.8",
      "thinking_variant": "claude-opus-4-8-thinking"
    },
    {
      "id": "claude-opus-4-8-thinking",
      "name": "Claude Opus 4.8 (Thinking)"
    },
    {
      "id": "claude-sonnet-5",
      "name": "Claude Sonnet 5",
      "thinking_variant": "claude-sonnet-5-thinking"
    }
  ]
}
필드유형설명
idstring안정적인 모델 식별자. 메시지 보내기 또는 모델 호출에서 model 값으로 전달하세요
namestring사람이 읽기 쉬운 표시 이름
thinking_variantstring사고/추론 변형의 모델 ID. 추론을 지원하는 기본 모델에만 존재함

thinking_variant가 있는 모델은 확장 추론을 지원합니다. 이를 활성화하려면 model 필드에 변형 ID를 직접 사용하세요.

메시지를 보낼 때 model을 지정하지 않으면 세션의 model이 사용됩니다. 이 값은 세션 생성 시 에이전트의 기본 모델로 설정됩니다.


모델 호출

POST /invoke

에이전트, 세션, 도구 없이 프롬프트를 모델에 직접 보냅니다. 응답은 기본적으로 SSE를 통해 스트리밍되며, JSON으로 받으려면 stream: false로 설정하세요.

요청 본문

필드유형필수기본값설명
modelstring필수-모델 목록 조회의 모델 ID
contentstring필수-지침을 포함한 프롬프트
streamboolean선택trueSSE 스트리밍의 경우 true, JSON의 경우 false
userstring선택-귀하의 외부 최종 사용자 식별자(최대 255자). 생략하면 귀하의 개발자 계정으로 기본 설정됩니다

예시

curl -X POST https://api.jenova.ai/v1/invoke \
  -H "Authorization: Bearer jnv_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "content": "Describe a forest in one sentence.",
    "stream": false
  }'

응답 200 OK

{
  "id": "inv_abc123",
  "model": "claude-sonnet-5",
  "content": "Sunlight filters through tall pines onto a quiet, mossy floor.",
  "usage": {
    "cost": "0.0004"
  }
}

스트리밍 응답은 stream_started를 보낸 다음, 모델이 텍스트를 생성하는 동안 stream_delta 이벤트를 보내고, usage가 포함된 stream_ended로 끝납니다. seq 순서대로 chunk_content 값을 연결하여 스트리밍된 응답을 구성하십시오. 요청이 실패하면 stream_ended 전에 stream_error가 전송됩니다. 이벤트에는 session_id와 run_id 대신 id가 포함됩니다.

비용을 확인할 수 없는 경우 usage.cost는 null입니다. 모델 호출이 시작된 후 비스트리밍 요청이 실패하면 오류 응답에 최상위 id 및 usage 필드가 포함됩니다.

스트리밍 요청은 최대 120분으로 제한됩니다. 비스트리밍 요청은 202 Accepted를 반환하는 대신 결과를 최대 30분까지 기다리며, 그때까지 결과가 준비되지 않으면 오류를 반환합니다.

오류

상태코드조건
400invalid_payload잘못된 형식의 JSON이거나 필드의 유형이 유효하지 않습니다
400missing_required_fieldcontent는 필수입니다
400content_too_long콘텐츠가 32,000 토큰을 초과했습니다
400bad_requestuser가 최대 길이를 초과했습니다
400invalid_model_selectionmodel이 없거나 유효한 모델 ID가 아닙니다
400content_policy_violation모델 제공업체가 콘텐츠 정책 위반을 이유로 요청을 거부함
400llm_context_limit_reached입력이 모델의 컨텍스트 창을 초과함
402insufficient_credits모델을 호출하기에 크레딧이 충분하지 않습니다
500internal_error예기치 않은 서버 오류
502llm_api_error모델 제공업체 또는 상위 모델 API 오류
502llm_empty_response모델이 빈 응답을 반환함
502llm_reasoning_limit_reached모델이 응답 없이 추론 한도에 도달함
502llm_generation_limit_reached모델이 응답 없이 생성 한도에 도달함
503service_unavailable서비스를 일시적으로 사용할 수 없음

문서

GET /docs?lang=en
GET /doc?lang=en

이 참조 문서를 Markdown 형식으로 반환합니다. 언어를 선택하려면 lang을 사용하세요.


스트리밍 (SSE)

stream이 생략되거나 true(기본값)인 경우, 메시지 응답은 Server-Sent Events로 전달됩니다. 가져오거나 렌더링할 준비가 된 메시지를 식별하려면 message_completed 이벤트를 사용하세요.

타임아웃: SSE 연결은 실행이 끝날 때까지 유지됩니다. 실행 시간은 최대 120분으로 제한됩니다. 비스트리밍 메시지 요청은 최대 90초까지 대기한 후, 실행이 계속되는 동안 202 Accepted를 반환합니다. 비스트리밍 POST /invoke에 대해서는 모델 호출을 참조하십시오.

연결 헤더

메시지 스트림은 다음 헤더를 설정합니다:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123

X-Run-Id는 첫 SSE 이벤트 이전에 사용할 수 있습니다. POST /invoke 스트림은 X-Run-Id를 설정하지 않으므로 stream_started의 id를 사용하세요.

재연결 및 복구

SSE 스트림은 재생되지 않습니다. 지속 요청에서 연결이 끊어진 경우, 캡처해 둔 session_id와 run_id를 사용하여 상태를 복구하세요:

curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
  -H "Authorization: Bearer jnv_sk_xxx"

실행이 아직 활성 상태라면, 현재 상태, 부분 텍스트, 최근 진행 상황이 반환됩니다. status: "ended" 또는 404 not_found가 반환되면 해당 실행은 더 이상 활성 상태가 아니므로, 세션의 메시지를 가져와 완료된 출력을 대조하세요:

curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
  -H "Authorization: Bearer jnv_sk_xxx"

프레임 형식

각 SSE 프레임은 다음과 같은 표준 형식을 따릅니다:

event: <event_type>
data: <json_payload>

두 개의 줄바꿈이 각 프레임을 종료합니다.

이벤트 유형

스트림에는 수명 주기, 텍스트 델타, 사고, 진행 상황, 경고, 메시지 완료, MCP 연결, 오류, 최종 및 ping 이벤트가 포함됩니다. 일부 이벤트 유형은 관련이 있을 때만 전송됩니다.

일시적(ephemeral) 요청(ephemeral: true)의 경우, 모든 SSE 이벤트에서 session_id가 생략됩니다. 해당 단일 스트림 내에서 이벤트를 연관시키려면 run_id만 사용하십시오.

영구(persistent) 요청에 대한 최종 조정을 위해서는 stream_ended를 기다린 다음 메시지 목록 조회를 호출하십시오.

실행 범위 이벤트에 공통되는 필드:

필드설명
session_id세션 ID. 일시적 스트림에서는 생략됩니다. 영구적인 POST /messages를 사용할 때 후속 요청을 위해 stream_started에서 이 값을 캡처하십시오
run_id사용 가능한 경우 현재 실행 ID
idinvoke 요청 ID(inv_ 접두사 포함). session_id나 run_id가 없는 POST /invoke 스트림에만 존재

stream_started

실행이 시작될 때 한 번 전송됩니다.

필드설명
agent사용 가능한 경우 세션 에이전트 슬러그

stream_delta

에이전트가 표시되는 응답 텍스트를 생성하는 동안 반복적으로 전송됩니다. seq 순서대로 chunk_content 값을 연결하여 스트리밍된 응답을 구성하십시오.

event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
필드설명
chunk_content텍스트 청크
seq스트림 내 단조 증가하는 청크 시퀀스

stream_thinking

에이전트가 사고(thinking) 출력을 내보내는 동안 반복적으로 전송됩니다. 별도의 사고 표시기나 추적 뷰에 사용하십시오. 최종 응답 텍스트에 연결하지 마십시오.

필드설명
content사고 텍스트 청크

stream_progress

문서 읽기, 웹 검색 또는 사용자 작업 대기와 같이 생성 중 사용자에게 표시되는 활동을 보고합니다. 이러한 이벤트는 임시 UI 표시용입니다. 알 수 없는 필드는 무시하세요. 권위 있는 메시지 기록에는 완료된 메시지를 사용하세요.

메시지 요청에 include_progress: false를 설정하면 stream_progress만 생략됩니다. 라이프사이클 이벤트, ping, message_completed, 오류 및 종료 이벤트는 관련이 있을 경우 여전히 전송됩니다.

필드설명
state활동 상태: running, success, failed 또는 skipped. 알 수 없는 값도 정상적으로 처리하십시오
label사람이 읽을 수 있는 활동 레이블

일부 진행 상황 이벤트에는 선택적 표시 힌트로 url, file_name, 또는 server_name이 포함될 수 있습니다.

message_completed

메시지가 완료되어 가져오거나 렌더링할 준비가 될 때마다 전송됩니다.

이것은 경계 마커일 뿐, 전체 메시지 객체가 아닙니다. 콘텐츠나 메타데이터가 필요한 경우 메시지를 가져오십시오.

event: message_completed
data: {"session_id":"ses_abc123","run_id":"run_abc123","message_id":"msg_abc123","sequence":4,"from":{"type":"agent","name":"my-support-agent"},"type":"external"}
필드설명
message_id완료된 메시지 ID
sequence세션 내 순서 번호
fromtype(user 또는 agent)과 name을 포함하는 발신자 객체
type메시지 유형: external 또는 internal

mcp_connection

에이전트가 계속하기 전에 최종 사용자가 하나 이상의 MCP 서버를 연결하거나 승인해야 할 때 전송됩니다. 이 이벤트는 스트리밍 모드에서만 사용할 수 있습니다.

필드설명
connection_server_list연결 작업이 필요한 MCP 서버. 각 서버에는 mcp_server_id, mcp_server_name, 선택 사항인 auth_url이 포함됩니다
user_action_deadline_unix연결 사용자 작업이 만료되는 Unix 타임스탬프

mcp_connection_resolved

MCP 연결 사용자 작업이 해결되었거나 만료되었을 때 전송됩니다.

공통 실행 범위 필드 외에 추가 필드는 없습니다.

warning

실행 중 치명적이지 않은 경고에 대해 전송됩니다.

필드설명
message사람이 읽을 수 있는 치명적이지 않은 경고
code선택적 경고 코드

stream_error

실행이 실패했을 때 전송됩니다. 이어서 success: false 및 stop_reason: "error"가 포함된 최종 stream_ended 이벤트가 뒤따를 수 있습니다.

필드설명
code오류 코드
message사람이 읽을 수 있는 오류 메시지

stream_ended

실행이 종료되면 한 번 전송됩니다. 이는 스트림의 마지막 이벤트입니다.

event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}

취소된 실행 예시:

event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
필드설명
success실행이 성공적으로 완료되었는지 여부
stop_reason실행 종료 이유: end_run, user_cancelled, user_action_timeout, 또는 error
usage이 요청에 대한 사용량 객체. cost는 항상 포함되며, 비용을 확인할 수 없는 경우 null입니다

ping

프록시/CDN 타임아웃을 방지하기 위해 15초마다 전송되는 킵얼라이브 프레임입니다. 클라이언트에서는 무시하십시오.


MCP 서버 통합

**Model Context Protocol (MCP)**을 통해 귀하의 에이전트를 외부 도구에 연결하십시오:

  • Jenova 관리형 MCP 서버: 검색, 콘텐츠 검색, 문서 생성 및 기타 기본 제공 기능을 위해 Jenova가 호스팅하는 서버
  • 원격 MCP 서버: 귀하의 에이전트를 위해 구성된 기타 원격 MCP 서버

MCP 서버는 에이전트를 생성하거나 편집할 때 대시보드에서 구성해야 합니다. 자체 MCP 서버를 사용하려면 이를 커스텀 에이전트에 추가한 다음 API를 통해 해당 에이전트를 호출하십시오. API는 에이전트 구성에서 활성화된 도구를 실행하며, API 요청에서 추가 설정이 필요하지 않습니다.

에이전트가 응답 중 MCP 도구를 사용할 때, 진행 이벤트는 발생하는 대로 스트림으로 전송됩니다:

event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}

실행 중 에이전트가 최종 사용자에게 MCP 서버 연결 또는 승인을 요구하는 경우, 스트리밍 응답에 mcp_connection 및 mcp_connection_resolved 이벤트가 포함될 수 있습니다. 최종 사용자에게 연결 서버 목록을 표시하고, 제공된 auth_url이 있으면 여세요. 최종 사용자가 서버를 연결하거나 승인하는 동안 SSE 스트림을 열어 두세요.

승인이 완료되면 Jenova가 토큰을 저장하고, 승인 창에는 완료 페이지가 표시되며, 동일한 실행이 자동으로 계속됩니다. 최종 사용자는 메시지를 다시 보낼 필요가 없습니다.

최종 사용자가 user_action_deadline_unix 전에 연결, 승인 또는 건너뛰기나 음소거를 하지 않으면 실행은 stop_reason: "user_action_timeout"으로 종료됩니다. POST /sessions/{session_id}/cancel로 활성 실행을 취소할 수도 있습니다.

auth_url을 클라이언트 측에 저장하세요. 승인 중 클라이언트 연결이 끊어져도 이 URL은 user_action_deadline_unix까지 유효합니다. 지속 요청의 경우 실행 상태 조회로 실행을 확인하거나 실행이 끝난 후 메시지를 가져오세요.

비스트리밍 요청(stream: false)은 MCP 연결 사용자 작업을 지원하지 않습니다. 이 상호작용이 필요할 수 있는 에이전트에는 스트리밍을 사용하세요.

MCP 연결 건너뛰기

POST /sessions/{session_id}/mcp/connection/skip

대기 중인 MCP 연결 사용자 작업을 무시하고 해당 연결 없이 실행을 계속하도록 합니다.

동일한 최종 사용자와 에이전트에 대해 한 서버의 향후 연결 프롬프트를 음소거하려면 mcp_server_id와 mute를 포함하세요. mute에는 30m, 24h, 7d와 같은 기간 또는 forever를 지정할 수 있습니다.

요청 본문

필드유형필수설명
run_idstring예mcp_connection 이벤트의 활성 실행 ID
mcp_server_idstring아니요mute 사용 시 필수입니다. 이벤트의 mcp_server_id를 사용하세요
mutestring아니요30m, 24h, 7d와 같은 기간 또는 forever

응답 204 No Content

스트림은 mcp_connection_resolved를 내보낸 다음, 실행은 동일한 run_id로 계속됩니다.

오류

상태코드조건
400invalid_payloadJSON 형식이 잘못되었거나 필드 유형이 올바르지 않음
400bad_requestrun_id가 없거나, 활성 실행이 없거나, 건너뛸 MCP 연결이 없음
400bad_request잘못된 mute, mute가 설정되었지만 mcp_server_id가 없음, 또는 mcp_server_id가 이 세션에 유효하지 않음
404session_not_found세션이 존재하지 않음
404session_not_owned세션이 다른 개발자에게 속하거나 지정된 user와 일치하지 않음
409stale_runrun_id가 활성 실행과 일치하지 않음

결제

모든 비용은 귀하의 개발자 크레딧 잔액에서 차감됩니다. www.jenova.ai/platform에서 사용량을 확인하고 크레딧을 충전할 수 있습니다.

가격

작업비용
세션 생성POST /sessions 또는 POST /messages로 생성되는 지속 세션마다 $0.01 고정 요금
세션 포크$0.05 고정(별도의 세션 생성 요금 없음)
메시지 전송가변 (아래 참조)
모델 호출가변 (모델 및 토큰 기준)

메시지 비용은 다음에 따라 결정됩니다:

  • 모델 - 모델마다 토큰당 비용이 다릅니다
  • 컨텍스트 길이 - 세션이 길어질수록 요청당 더 많은 입력 토큰을 소비합니다
  • 워크플로 복잡도 - 워크플로가 길어지고 도구 사용(웹 검색, 파일 생성, 문서 분석)이 늘어나면 전체 토큰 소비량이 증가합니다

실제 비용은 스트리밍 요청의 경우 stream_ended.usage.cost로, 비스트리밍 JSON 요청의 경우 usage.cost로 반환됩니다.

크레딧 보류

각 POST /messages, POST /sessions/{session_id}/messages, POST /invoke 요청은 실행이 시작되기 전에 귀하의 크레딧 잔액에 $0.50 보류를 설정합니다. 이는 요청을 위한 자금을 예약하는 것입니다. 활성 실행에 대기열로 추가된 메시지(status: "queued"와 함께 202 Accepted)는 추가 보류를 생성하지 않으며, 활성 실행의 사용량은 귀하의 남은 잔액과 대조하여 확인됩니다.

요청이 완료되면 보류는 실제 비용으로 정산되며 차액은 해제됩니다. 실제 비용이 보류 금액을 초과하면 차액도 청구되므로 잔액이 0 미만으로 내려갈 수 있습니다. 취소되거나 실패한 요청은 이미 발생한 사용량에 대해서만 청구됩니다. 요청이 모델에 도달하기 전에 실패하면 전체 보류가 해제됩니다.

보류로 인해 진행 중인 요청 동안 귀하의 사용 가능한 잔액이 일시적으로 낮게 표시될 수 있습니다. POST /sessions/{session_id}/messages, 임시 POST /messages 또는 POST /invoke 요청에는 최소 $0.50의 사용 가능한 잔액이 필요합니다. 지속 세션 POST /messages 요청은 세션도 생성하므로, 보류 금액과 세션 생성 요금을 충당하기 위해 최소 $0.51이 필요합니다.


속도 제한

모든 개발자 계정은 세 가지 속도 제한 차원의 적용을 받습니다:

차원기본값설명
RPM (분당 요청 수)20060초 고정 윈도우
RPD (일일 요청 수)10,00024시간 고정 윈도우
동시 실행10동시에 진행 중인 요청 및 활성 실행의 최대 수

실행은 202 Accepted 응답이 반환되거나 클라이언트 연결이 끊긴 후에도 종료될 때까지 동시 슬롯을 유지합니다. POST /invoke 요청은 클라이언트 연결이 끊겨도 완료될 때까지 슬롯을 유지합니다.

GET 및 HEAD 요청은 동시 슬롯을 소비하지 않습니다. cancel, undo, mcp/connection/skip도 동시 슬롯을 소비하지 않으므로 모든 슬롯이 사용 중이어도 이러한 작업은 계속 사용할 수 있습니다. 이러한 요청은 여전히 RPM 및 RPD에 계산됩니다.

이와 별도로 모든 요청에 60초당 1,200건의 IP별 제한이 적용되며, 초과 시 동일한 429 rate_limit_exceeded 오류가 반환됩니다.

응답 헤더

인증된 API 응답에는 속도 제한 헤더가 포함됩니다:

헤더설명
X-RateLimit-Limit귀하의 RPM 제한
X-RateLimit-Remaining현재 1분 윈도우 내 남은 요청 수
X-RateLimit-Reset현재 윈도우가 재설정되는 Unix 타임스탬프
Retry-After재시도 전 대기해야 하는 시간(초). 429 rate_limit_exceeded 및 503 write_freeze_active 응답에서 전송됨

일일 한도를 초과한 경우 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset은 대신 일일 윈도우를 기준으로 표시됩니다.

제한을 초과하면 API는 429 Too Many Requests를 반환합니다:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please try again later."
  }
}

오류 처리

즉시 발생하는 HTTP 오류와 스트리밍이 아닌 실행 오류는 일관된 형식을 따릅니다:

{
  "error": {
    "code": "error_code_string",
    "message": "Human-readable description"
  }
}

오류 메시지는 lang 또는 Accept-Language를 기준으로 현지화됩니다(현지화 참고).

스트리밍 실행 오류는 stream_error 이벤트로 전달됩니다. 실패한 실행이라도 success: false와 stop_reason이 설정된 최종 stream_ended 이벤트가 전송될 수 있습니다. 스트리밍이 아닌 실행 오류에는 최상위 usage 객체가 포함되며, 비용을 확인할 수 없는 경우 cost는 null입니다.

다음 오류는 모든 엔드포인트에서 발생할 수 있습니다:

상태코드조건
401invalid_api_keyAPI 키가 없거나, 유효하지 않거나, 폐기됨
402developer_not_activated개발자 계정이 아직 활성화되지 않음. 대시보드에서 크레딧을 구매하여 활성화하세요
403developer_disabled개발자 계정이 비활성화됨
403forbidden이 네트워크의 요청이 차단됨
413payload_too_large요청 본문이 1 MiB를 초과함
429rate_limit_exceeded속도 제한을 초과함. 속도 제한을 참조하세요
503write_freeze_active유지 관리로 인해 쓰기 요청이 일시적으로 비활성화됨

엔드포인트별 오류는 각 엔드포인트 하위에 인라인으로 문서화되어 있습니다.

시작 후 실행 오류

실행 오류는 메시지 요청이 수락된 후에 나타납니다. 스트리밍 모드에서는 stream_error 이벤트로 나타나며, 이후 success: false가 설정된 stream_ended가 이어질 수 있습니다. 스트리밍이 아닌 모드에서는 아래 HTTP 상태와 함께 JSON 오류 응답으로 반환됩니다.

스트리밍이 아닌 경우의 HTTP 상태코드조건
400content_policy_violation모델 제공업체가 콘텐츠 정책 위반을 이유로 요청을 거부함
400llm_context_limit_reached입력이 모델의 컨텍스트 창을 초과함
404session_not_found실행이 실행되기 전에 세션이 삭제됨
409busy실행이 시작되기 전에 세션이 사용 중 상태가 되거나 일시적으로 이용할 수 없게 됨
413total_image_size_exceeded결합된 이미지 페이로드가 모델의 요청당 크기 제한을 초과함
500internal_error예기치 않은 실행 실패
500response_interrupted실행이 중단됨. 메시지를 다시 보내세요
500response_interrupted_message_saved메시지가 저장된 후 실행이 중단됨. 다시 보내기 전에 세션의 메시지를 조회하세요
502llm_api_error모델 제공업체 또는 상위 모델 API 오류
502llm_empty_response모델이 빈 응답을 반환함
502llm_reasoning_limit_reached모델이 응답 없이 추론 한도에 도달함
502llm_generation_limit_reached모델이 응답 없이 생성 한도에 도달함

페이지네이션

세션 목록 조회와 메시지 목록 조회는 커서 기반 페이지네이션을 사용합니다:

{
  "items": [],
  "next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
  "has_more": true
}
파라미터유형기본값최대값설명
limitinteger20100페이지당 항목 수
cursorstring--이전 next_cursor에서 얻은 불투명 커서

다음 페이지를 가져오려면 next_cursor 값을 URL 인코딩하여 cursor 쿼리 파라미터로 전달하십시오. has_more가 false이면 더 이상 결과가 없습니다. limit이 1-100 범위를 벗어나거나 커서가 유효하지 않으면 400 bad_request가 반환됩니다.


현지화

모든 엔드포인트는 오류 메시지 및 현지화된 콘텐츠의 언어를 제어하기 위해 선택적 lang 쿼리 파라미터를 허용합니다.

소스우선순위예시
lang 쿼리 파라미터최고?lang=zh
Accept-Language 헤더대체Accept-Language: ja
기본값최저English (en)

모든 요청 URL에 ?lang=xx를 추가할 수 있습니다:

POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja

지원 언어: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi


개인정보 보호 및 데이터

Jenova는 Jenova 모델을 훈련시키기 위해 API 프롬프트, 출력, 대화 기록, 업로드된 파일, 에이전트 지시사항 또는 지식 베이스를 사용하지 않습니다.

Jenova는 제3자 모델 제공업체와 관련하여, 고객 콘텐츠가 제공업체 모델 훈련에 사용되지 않도록 하기 위해 상업용 API 채널, 계정 설정, 계약상 약속 또는 옵트아웃을 활용합니다.

Jenova는 미국 인프라를 사용하여 API 데이터를 저장하고 처리합니다. 제3자 제공업체는 개인정보 보호정책 및 이용약관에 설명된 대로 다른 관할권에서 데이터를 처리할 수 있습니다.

전체 내용은 이용약관, 개인정보 보호정책, 사용 정책을 참조하십시오.


지원