From 2b29c8c258c551173b8e894e604cd812874dcab1 Mon Sep 17 00:00:00 2001 From: waleed Date: Sun, 1 Feb 2026 20:15:54 -0800 Subject: [PATCH] feat(api): add dedicated api endpoint, update docs, update deploy modal --- apps/docs/content/docs/de/execution/api.mdx | 4 ++-- apps/docs/content/docs/de/execution/costs.mdx | 2 +- apps/docs/content/docs/de/sdks/python.mdx | 2 +- apps/docs/content/docs/de/sdks/typescript.mdx | 2 +- apps/docs/content/docs/en/execution/api.mdx | 4 ++-- apps/docs/content/docs/en/execution/costs.mdx | 2 +- apps/docs/content/docs/en/execution/form.mdx | 8 ++++---- apps/docs/content/docs/en/sdks/python.mdx | 2 +- apps/docs/content/docs/en/sdks/typescript.mdx | 2 +- apps/docs/content/docs/es/execution/api.mdx | 4 ++-- apps/docs/content/docs/es/execution/costs.mdx | 2 +- apps/docs/content/docs/es/sdks/python.mdx | 2 +- apps/docs/content/docs/es/sdks/typescript.mdx | 2 +- apps/docs/content/docs/fr/execution/api.mdx | 4 ++-- apps/docs/content/docs/fr/execution/costs.mdx | 2 +- apps/docs/content/docs/fr/sdks/python.mdx | 2 +- apps/docs/content/docs/fr/sdks/typescript.mdx | 2 +- apps/docs/content/docs/ja/execution/api.mdx | 4 ++-- apps/docs/content/docs/ja/execution/costs.mdx | 2 +- apps/docs/content/docs/ja/sdks/python.mdx | 2 +- apps/docs/content/docs/ja/sdks/typescript.mdx | 2 +- apps/docs/content/docs/zh/execution/api.mdx | 4 ++-- apps/docs/content/docs/zh/execution/costs.mdx | 2 +- apps/docs/content/docs/zh/sdks/python.mdx | 2 +- apps/docs/content/docs/zh/sdks/typescript.mdx | 2 +- .../components/deploy-modal/deploy-modal.tsx | 4 ++-- .../utils/workflow-execution-utils.ts | 4 +++- apps/sim/blocks/blocks/api_trigger.ts | 2 +- apps/sim/hooks/use-execution-stream.ts | 17 ++++++++++++----- .../workflow/check-deployment-status.ts | 4 +++- .../tools/client/workflow/deploy-api.ts | 6 +++--- apps/sim/lib/core/config/env.ts | 2 ++ apps/sim/lib/core/utils/urls.ts | 19 +++++++++++++++++++ packages/python-sdk/README.md | 8 ++++---- packages/python-sdk/simstudio/__init__.py | 6 +++--- packages/python-sdk/tests/test_client.py | 4 ++-- packages/ts-sdk/README.md | 4 ++-- packages/ts-sdk/examples/basic-usage.ts | 2 +- packages/ts-sdk/src/index.ts | 2 +- 39 files changed, 92 insertions(+), 60 deletions(-) diff --git a/apps/docs/content/docs/de/execution/api.mdx b/apps/docs/content/docs/de/execution/api.mdx index fbfa995e6..b83b85099 100644 --- a/apps/docs/content/docs/de/execution/api.mdx +++ b/apps/docs/content/docs/de/execution/api.mdx @@ -14,7 +14,7 @@ Alle API-Anfragen erfordern einen API-Schlüssel, der im Header `x-api-key` übe ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` Sie können API-Schlüssel in Ihren Benutzereinstellungen im Sim-Dashboard generieren. @@ -528,7 +528,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/de/execution/costs.mdx b/apps/docs/content/docs/de/execution/costs.mdx index 743d43d93..0a8918158 100644 --- a/apps/docs/content/docs/de/execution/costs.mdx +++ b/apps/docs/content/docs/de/execution/costs.mdx @@ -142,7 +142,7 @@ GET /api/users/me/usage-limits **Beispielanfrage:** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **Beispielantwort:** diff --git a/apps/docs/content/docs/de/sdks/python.mdx b/apps/docs/content/docs/de/sdks/python.mdx index cbe7ad995..6dca59ab1 100644 --- a/apps/docs/content/docs/de/sdks/python.mdx +++ b/apps/docs/content/docs/de/sdks/python.mdx @@ -647,7 +647,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/de/sdks/typescript.mdx b/apps/docs/content/docs/de/sdks/typescript.mdx index fed552b84..626b5c5bc 100644 --- a/apps/docs/content/docs/de/sdks/typescript.mdx +++ b/apps/docs/content/docs/de/sdks/typescript.mdx @@ -965,7 +965,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/docs/content/docs/en/execution/api.mdx b/apps/docs/content/docs/en/execution/api.mdx index 860b44571..d10f1d7c6 100644 --- a/apps/docs/content/docs/en/execution/api.mdx +++ b/apps/docs/content/docs/en/execution/api.mdx @@ -14,7 +14,7 @@ All API requests require an API key passed in the `x-api-key` header: ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` You can generate API keys from your user settings in the Sim dashboard. @@ -513,7 +513,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/en/execution/costs.mdx b/apps/docs/content/docs/en/execution/costs.mdx index 5d88091b1..65d5fd55b 100644 --- a/apps/docs/content/docs/en/execution/costs.mdx +++ b/apps/docs/content/docs/en/execution/costs.mdx @@ -160,7 +160,7 @@ GET /api/users/me/usage-limits **Example Request:** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **Example Response:** diff --git a/apps/docs/content/docs/en/execution/form.mdx b/apps/docs/content/docs/en/execution/form.mdx index 3df49004e..ffeab43a5 100644 --- a/apps/docs/content/docs/en/execution/form.mdx +++ b/apps/docs/content/docs/en/execution/form.mdx @@ -82,7 +82,7 @@ Submit forms programmatically: ```bash -curl -X POST https://sim.ai/api/form/your-identifier \ +curl -X POST https://api.sim.ai/api/form/your-identifier \ -H "Content-Type: application/json" \ -d '{ "formData": { @@ -94,7 +94,7 @@ curl -X POST https://sim.ai/api/form/your-identifier \ ```typescript -const response = await fetch('https://sim.ai/api/form/your-identifier', { +const response = await fetch('https://api.sim.ai/api/form/your-identifier', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -115,14 +115,14 @@ const result = await response.json(); For password-protected forms: ```bash -curl -X POST https://sim.ai/api/form/your-identifier \ +curl -X POST https://api.sim.ai/api/form/your-identifier \ -H "Content-Type: application/json" \ -d '{ "password": "secret", "formData": { "name": "John" } }' ``` For email-protected forms: ```bash -curl -X POST https://sim.ai/api/form/your-identifier \ +curl -X POST https://api.sim.ai/api/form/your-identifier \ -H "Content-Type: application/json" \ -d '{ "email": "allowed@example.com", "formData": { "name": "John" } }' ``` diff --git a/apps/docs/content/docs/en/sdks/python.mdx b/apps/docs/content/docs/en/sdks/python.mdx index 3ab1cdee7..e6531e01b 100644 --- a/apps/docs/content/docs/en/sdks/python.mdx +++ b/apps/docs/content/docs/en/sdks/python.mdx @@ -655,7 +655,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/en/sdks/typescript.mdx b/apps/docs/content/docs/en/sdks/typescript.mdx index 6364384c8..63c409713 100644 --- a/apps/docs/content/docs/en/sdks/typescript.mdx +++ b/apps/docs/content/docs/en/sdks/typescript.mdx @@ -948,7 +948,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/docs/content/docs/es/execution/api.mdx b/apps/docs/content/docs/es/execution/api.mdx index a08eca485..e04dd30b0 100644 --- a/apps/docs/content/docs/es/execution/api.mdx +++ b/apps/docs/content/docs/es/execution/api.mdx @@ -14,7 +14,7 @@ Todas las solicitudes a la API requieren una clave de API pasada en el encabezad ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` Puedes generar claves de API desde la configuración de usuario en el panel de control de Sim. @@ -528,7 +528,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/es/execution/costs.mdx b/apps/docs/content/docs/es/execution/costs.mdx index 59c5d386a..64c4b77ae 100644 --- a/apps/docs/content/docs/es/execution/costs.mdx +++ b/apps/docs/content/docs/es/execution/costs.mdx @@ -142,7 +142,7 @@ GET /api/users/me/usage-limits **Solicitud de ejemplo:** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **Respuesta de ejemplo:** diff --git a/apps/docs/content/docs/es/sdks/python.mdx b/apps/docs/content/docs/es/sdks/python.mdx index cff0a2468..7bc2e348d 100644 --- a/apps/docs/content/docs/es/sdks/python.mdx +++ b/apps/docs/content/docs/es/sdks/python.mdx @@ -656,7 +656,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/es/sdks/typescript.mdx b/apps/docs/content/docs/es/sdks/typescript.mdx index 58c3578c2..954eee66e 100644 --- a/apps/docs/content/docs/es/sdks/typescript.mdx +++ b/apps/docs/content/docs/es/sdks/typescript.mdx @@ -965,7 +965,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/docs/content/docs/fr/execution/api.mdx b/apps/docs/content/docs/fr/execution/api.mdx index 669e41acf..4be390e46 100644 --- a/apps/docs/content/docs/fr/execution/api.mdx +++ b/apps/docs/content/docs/fr/execution/api.mdx @@ -14,7 +14,7 @@ Toutes les requêtes API nécessitent une clé API transmise dans l'en-tête `x- ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` Vous pouvez générer des clés API depuis vos paramètres utilisateur dans le tableau de bord Sim. @@ -528,7 +528,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/fr/execution/costs.mdx b/apps/docs/content/docs/fr/execution/costs.mdx index e18e7b86a..cf0d2cf11 100644 --- a/apps/docs/content/docs/fr/execution/costs.mdx +++ b/apps/docs/content/docs/fr/execution/costs.mdx @@ -142,7 +142,7 @@ GET /api/users/me/usage-limits **Exemple de requête :** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **Exemple de réponse :** diff --git a/apps/docs/content/docs/fr/sdks/python.mdx b/apps/docs/content/docs/fr/sdks/python.mdx index 268bc7657..fc027564e 100644 --- a/apps/docs/content/docs/fr/sdks/python.mdx +++ b/apps/docs/content/docs/fr/sdks/python.mdx @@ -656,7 +656,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/fr/sdks/typescript.mdx b/apps/docs/content/docs/fr/sdks/typescript.mdx index 0c6e98781..dbef676aa 100644 --- a/apps/docs/content/docs/fr/sdks/typescript.mdx +++ b/apps/docs/content/docs/fr/sdks/typescript.mdx @@ -965,7 +965,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/docs/content/docs/ja/execution/api.mdx b/apps/docs/content/docs/ja/execution/api.mdx index ce3c0b54a..f50f26f83 100644 --- a/apps/docs/content/docs/ja/execution/api.mdx +++ b/apps/docs/content/docs/ja/execution/api.mdx @@ -14,7 +14,7 @@ Simは、ワークフローの実行ログを照会したり、ワークフロ ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` SimダッシュボードのユーザーセッティングからAPIキーを生成できます。 @@ -528,7 +528,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/ja/execution/costs.mdx b/apps/docs/content/docs/ja/execution/costs.mdx index 5c4f1def1..a9c619c31 100644 --- a/apps/docs/content/docs/ja/execution/costs.mdx +++ b/apps/docs/content/docs/ja/execution/costs.mdx @@ -142,7 +142,7 @@ GET /api/users/me/usage-limits **リクエスト例:** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **レスポンス例:** diff --git a/apps/docs/content/docs/ja/sdks/python.mdx b/apps/docs/content/docs/ja/sdks/python.mdx index de4467f8a..9cc6bb253 100644 --- a/apps/docs/content/docs/ja/sdks/python.mdx +++ b/apps/docs/content/docs/ja/sdks/python.mdx @@ -656,7 +656,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/ja/sdks/typescript.mdx b/apps/docs/content/docs/ja/sdks/typescript.mdx index a224c7663..1c33e5991 100644 --- a/apps/docs/content/docs/ja/sdks/typescript.mdx +++ b/apps/docs/content/docs/ja/sdks/typescript.mdx @@ -965,7 +965,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/docs/content/docs/zh/execution/api.mdx b/apps/docs/content/docs/zh/execution/api.mdx index b1b8e5f35..0df0a31fd 100644 --- a/apps/docs/content/docs/zh/execution/api.mdx +++ b/apps/docs/content/docs/zh/execution/api.mdx @@ -14,7 +14,7 @@ Sim 提供了一个全面的外部 API,用于查询工作流执行日志,并 ```bash curl -H "x-api-key: YOUR_API_KEY" \ - https://sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID + https://api.sim.ai/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID ``` 您可以在 Sim 仪表板的用户设置中生成 API 密钥。 @@ -528,7 +528,7 @@ async function pollLogs() { } const response = await fetch( - `https://sim.ai/api/v1/logs?${params}`, + `https://api.sim.ai/api/v1/logs?${params}`, { headers: { 'x-api-key': 'YOUR_API_KEY' diff --git a/apps/docs/content/docs/zh/execution/costs.mdx b/apps/docs/content/docs/zh/execution/costs.mdx index 349039c19..84d2b8123 100644 --- a/apps/docs/content/docs/zh/execution/costs.mdx +++ b/apps/docs/content/docs/zh/execution/costs.mdx @@ -142,7 +142,7 @@ GET /api/users/me/usage-limits **请求示例:** ```bash -curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://sim.ai/api/users/me/usage-limits +curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" https://api.sim.ai/api/users/me/usage-limits ``` **响应示例:** diff --git a/apps/docs/content/docs/zh/sdks/python.mdx b/apps/docs/content/docs/zh/sdks/python.mdx index c44973c86..54ef0b569 100644 --- a/apps/docs/content/docs/zh/sdks/python.mdx +++ b/apps/docs/content/docs/zh/sdks/python.mdx @@ -656,7 +656,7 @@ def stream_workflow(): def generate(): response = requests.post( - 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', + 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.getenv('SIM_API_KEY') diff --git a/apps/docs/content/docs/zh/sdks/typescript.mdx b/apps/docs/content/docs/zh/sdks/typescript.mdx index 0f038db92..7cdaf44a6 100644 --- a/apps/docs/content/docs/zh/sdks/typescript.mdx +++ b/apps/docs/content/docs/zh/sdks/typescript.mdx @@ -965,7 +965,7 @@ function StreamingWorkflow() { // IMPORTANT: Make this API call from your backend server, not the browser // Never expose your API key in client-side code - const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { + const response = await fetch('https://api.sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx index 4598318e0..7beae5b1c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx @@ -16,7 +16,7 @@ import { ModalTabsList, ModalTabsTrigger, } from '@/components/emcn' -import { getBaseUrl } from '@/lib/core/utils/urls' +import { getApiUrl } from '@/lib/core/utils/urls' import { getInputFormatExample as getInputFormatExampleUtil } from '@/lib/workflows/operations/deployment-utils' import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' import { CreateApiKeyModal } from '@/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/api-keys/components' @@ -201,7 +201,7 @@ export function DeployModal({ return null } - const endpoint = `${getBaseUrl()}/api/workflows/${workflowId}/execute` + const endpoint = `${getApiUrl()}/api/workflows/${workflowId}/execute` const inputFormatExample = getInputFormatExample(selectedStreamingOutputs.length > 0) const placeholderKey = getApiHeaderPlaceholder() diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts index c69670f8d..9bced51dd 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils.ts @@ -1,4 +1,5 @@ import { v4 as uuidv4 } from 'uuid' +import { getApiUrl } from '@/lib/core/utils/urls' import type { ExecutionResult, StreamingExecution } from '@/executor/types' import { useExecutionStore } from '@/stores/execution' import { useTerminalConsoleStore } from '@/stores/terminal' @@ -41,7 +42,8 @@ export async function executeWorkflowWithFullLogging( isClientSession: true, } - const response = await fetch(`/api/workflows/${activeWorkflowId}/execute`, { + const apiUrl = getApiUrl() + const response = await fetch(`${apiUrl}/api/workflows/${activeWorkflowId}/execute`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/apps/sim/blocks/blocks/api_trigger.ts b/apps/sim/blocks/blocks/api_trigger.ts index 59312c504..29d2dbe95 100644 --- a/apps/sim/blocks/blocks/api_trigger.ts +++ b/apps/sim/blocks/blocks/api_trigger.ts @@ -11,7 +11,7 @@ export const ApiTriggerBlock: BlockConfig = { bestPractices: ` - Can run the workflow manually to test implementation when this is the trigger point. - The input format determines variables accesssible in the following blocks. E.g. . You can set the value in the input format to test the workflow manually. - - In production, the curl would come in as e.g. curl -X POST -H "X-API-Key: $SIM_API_KEY" -H "Content-Type: application/json" -d '{"paramName":"example"}' https://www.staging.sim.ai/api/workflows/9e7e4f26-fc5e-4659-b270-7ea474b14f4a/execute -- If user asks to test via API, you might need to clarify the API key. + - In production, the curl would come in as e.g. curl -X POST -H "X-API-Key: $SIM_API_KEY" -H "Content-Type: application/json" -d '{"paramName":"example"}' https://api.sim.ai/api/workflows/9e7e4f26-fc5e-4659-b270-7ea474b14f4a/execute -- If user asks to test via API, you might need to clarify the API key. `, category: 'triggers', hideFromToolbar: true, diff --git a/apps/sim/hooks/use-execution-stream.ts b/apps/sim/hooks/use-execution-stream.ts index 5981d28f5..5cdb42103 100644 --- a/apps/sim/hooks/use-execution-stream.ts +++ b/apps/sim/hooks/use-execution-stream.ts @@ -1,5 +1,6 @@ import { useCallback, useRef } from 'react' import { createLogger } from '@sim/logger' +import { getApiUrl } from '@/lib/core/utils/urls' import type { BlockCompletedData, BlockErrorData, @@ -151,7 +152,8 @@ export function useExecutionStream() { currentExecutionRef.current = null try { - const response = await fetch(`/api/workflows/${workflowId}/execute`, { + const apiUrl = getApiUrl() + const response = await fetch(`${apiUrl}/api/workflows/${workflowId}/execute`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -211,7 +213,8 @@ export function useExecutionStream() { currentExecutionRef.current = null try { - const response = await fetch(`/api/workflows/${workflowId}/execute-from-block`, { + const apiUrl = getApiUrl() + const response = await fetch(`${apiUrl}/api/workflows/${workflowId}/execute-from-block`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -266,9 +269,13 @@ export function useExecutionStream() { const cancel = useCallback(() => { const execution = currentExecutionRef.current if (execution) { - fetch(`/api/workflows/${execution.workflowId}/executions/${execution.executionId}/cancel`, { - method: 'POST', - }).catch(() => {}) + const apiUrl = getApiUrl() + fetch( + `${apiUrl}/api/workflows/${execution.workflowId}/executions/${execution.executionId}/cancel`, + { + method: 'POST', + } + ).catch(() => {}) } if (abortControllerRef.current) { diff --git a/apps/sim/lib/copilot/tools/client/workflow/check-deployment-status.ts b/apps/sim/lib/copilot/tools/client/workflow/check-deployment-status.ts index a0d3de72e..522057b8c 100644 --- a/apps/sim/lib/copilot/tools/client/workflow/check-deployment-status.ts +++ b/apps/sim/lib/copilot/tools/client/workflow/check-deployment-status.ts @@ -5,6 +5,7 @@ import { type BaseClientToolMetadata, ClientToolCallState, } from '@/lib/copilot/tools/client/base-tool' +import { getApiUrl } from '@/lib/core/utils/urls' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' interface CheckDeploymentStatusArgs { @@ -103,11 +104,12 @@ export class CheckDeploymentStatusClientTool extends BaseClientTool { // API deployment details const isApiDeployed = apiDeploy?.isDeployed || false + const apiUrl = getApiUrl() const appUrl = typeof window !== 'undefined' ? window.location.origin : '' const apiDetails: ApiDeploymentDetails = { isDeployed: isApiDeployed, deployedAt: apiDeploy?.deployedAt || null, - endpoint: isApiDeployed ? `${appUrl}/api/workflows/${workflowId}/execute` : null, + endpoint: isApiDeployed ? `${apiUrl}/api/workflows/${workflowId}/execute` : null, apiKey: apiDeploy?.apiKey || null, needsRedeployment: apiDeploy?.needsRedeployment === true, } diff --git a/apps/sim/lib/copilot/tools/client/workflow/deploy-api.ts b/apps/sim/lib/copilot/tools/client/workflow/deploy-api.ts index c850dd493..4bd905838 100644 --- a/apps/sim/lib/copilot/tools/client/workflow/deploy-api.ts +++ b/apps/sim/lib/copilot/tools/client/workflow/deploy-api.ts @@ -6,7 +6,7 @@ import { ClientToolCallState, } from '@/lib/copilot/tools/client/base-tool' import { registerToolUIConfig } from '@/lib/copilot/tools/client/ui-config' -import { getBaseUrl } from '@/lib/core/utils/urls' +import { getApiUrl } from '@/lib/core/utils/urls' import { getInputFormatExample } from '@/lib/workflows/operations/deployment-utils' import { useCopilotStore } from '@/stores/panel/copilot/store' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' @@ -230,8 +230,8 @@ export class DeployApiClientTool extends BaseClientTool { } if (action === 'deploy') { - const appUrl = getBaseUrl() - const apiEndpoint = `${appUrl}/api/workflows/${workflowId}/execute` + const apiUrl = getApiUrl() + const apiEndpoint = `${apiUrl}/api/workflows/${workflowId}/execute` const apiKeyPlaceholder = '$SIM_API_KEY' const inputExample = getInputFormatExample(false) diff --git a/apps/sim/lib/core/config/env.ts b/apps/sim/lib/core/config/env.ts index 6bd9df299..eb727bdf8 100644 --- a/apps/sim/lib/core/config/env.ts +++ b/apps/sim/lib/core/config/env.ts @@ -307,6 +307,7 @@ export const env = createEnv({ client: { // Core Application URLs - Required for frontend functionality NEXT_PUBLIC_APP_URL: z.string().url(), // Base URL of the application (e.g., https://www.sim.ai) + NEXT_PUBLIC_API_URL: z.string().url().optional(), // API URL for workflow executions (e.g., https://api.sim.ai) // Client-side Services NEXT_PUBLIC_SOCKET_URL: z.string().url().optional(), // WebSocket server URL for real-time features @@ -357,6 +358,7 @@ export const env = createEnv({ experimental__runtimeEnv: { NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL, + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, NEXT_PUBLIC_BILLING_ENABLED: process.env.NEXT_PUBLIC_BILLING_ENABLED, NEXT_PUBLIC_SOCKET_URL: process.env.NEXT_PUBLIC_SOCKET_URL, NEXT_PUBLIC_BRAND_NAME: process.env.NEXT_PUBLIC_BRAND_NAME, diff --git a/apps/sim/lib/core/utils/urls.ts b/apps/sim/lib/core/utils/urls.ts index 22e164cf1..6bf8ad2a1 100644 --- a/apps/sim/lib/core/utils/urls.ts +++ b/apps/sim/lib/core/utils/urls.ts @@ -54,3 +54,22 @@ export function getEmailDomain(): string { return isProd ? 'sim.ai' : 'localhost:3000' } } + +/** + * Returns the API URL for workflow executions. + * Uses NEXT_PUBLIC_API_URL if configured, otherwise falls back to NEXT_PUBLIC_APP_URL. + * @returns The API URL string (e.g., 'https://api.sim.ai' or 'https://example.com') + */ +export function getApiUrl(): string { + const apiUrl = getEnv('NEXT_PUBLIC_API_URL') + + if (apiUrl) { + if (apiUrl.startsWith('http://') || apiUrl.startsWith('https://')) { + return apiUrl + } + const protocol = isProd ? 'https://' : 'http://' + return `${protocol}${apiUrl}` + } + + return getBaseUrl() +} diff --git a/packages/python-sdk/README.md b/packages/python-sdk/README.md index e193e951c..585bd923b 100644 --- a/packages/python-sdk/README.md +++ b/packages/python-sdk/README.md @@ -17,7 +17,7 @@ from simstudio import SimStudioClient # Initialize the client client = SimStudioClient( api_key=os.getenv("SIM_API_KEY", "your-api-key-here"), - base_url="https://sim.ai" # optional, defaults to https://sim.ai + base_url="https://api.sim.ai" # optional, defaults to https://api.sim.ai ) # Execute a workflow @@ -35,11 +35,11 @@ except Exception as error: #### Constructor ```python -SimStudioClient(api_key: str, base_url: str = "https://sim.ai") +SimStudioClient(api_key: str, base_url: str = "https://api.sim.ai") ``` - `api_key` (str): Your Sim API key -- `base_url` (str, optional): Base URL for the Sim API (defaults to `https://sim.ai`) +- `base_url` (str, optional): Base URL for the Sim API (defaults to `https://api.sim.ai`) #### Methods @@ -364,7 +364,7 @@ from simstudio import SimStudioClient # Using environment variables client = SimStudioClient( api_key=os.getenv("SIM_API_KEY"), - base_url=os.getenv("SIM_BASE_URL", "https://sim.ai") + base_url=os.getenv("SIM_BASE_URL", "https://api.sim.ai") ) ``` diff --git a/packages/python-sdk/simstudio/__init__.py b/packages/python-sdk/simstudio/__init__.py index ec242338e..465c9bed6 100644 --- a/packages/python-sdk/simstudio/__init__.py +++ b/packages/python-sdk/simstudio/__init__.py @@ -87,10 +87,10 @@ class SimStudioClient: Args: api_key: Your Sim API key - base_url: Base URL for the Sim API (defaults to https://sim.ai) + base_url: Base URL for the Sim API (defaults to https://api.sim.ai) """ - - def __init__(self, api_key: str, base_url: str = "https://sim.ai"): + + def __init__(self, api_key: str, base_url: str = "https://api.sim.ai"): self.api_key = api_key self.base_url = base_url.rstrip('/') self._session = requests.Session() diff --git a/packages/python-sdk/tests/test_client.py b/packages/python-sdk/tests/test_client.py index 8dfdee99b..6e9c458d4 100644 --- a/packages/python-sdk/tests/test_client.py +++ b/packages/python-sdk/tests/test_client.py @@ -18,7 +18,7 @@ def test_simstudio_client_default_base_url(): """Test SimStudioClient with default base URL.""" client = SimStudioClient(api_key="test-api-key") assert client.api_key == "test-api-key" - assert client.base_url == "https://sim.ai" + assert client.base_url == "https://api.sim.ai" def test_set_api_key(): @@ -51,7 +51,7 @@ def test_validate_workflow_returns_false_on_error(mock_get): result = client.validate_workflow("test-workflow-id") assert result is False - mock_get.assert_called_once_with("https://sim.ai/api/workflows/test-workflow-id/status") + mock_get.assert_called_once_with("https://api.sim.ai/api/workflows/test-workflow-id/status") def test_simstudio_error(): diff --git a/packages/ts-sdk/README.md b/packages/ts-sdk/README.md index 44d21d0c9..efedab65d 100644 --- a/packages/ts-sdk/README.md +++ b/packages/ts-sdk/README.md @@ -20,7 +20,7 @@ import { SimStudioClient } from 'simstudio-ts-sdk'; // Initialize the client const client = new SimStudioClient({ apiKey: 'your-api-key-here', - baseUrl: 'https://sim.ai' // optional, defaults to https://sim.ai + baseUrl: 'https://api.sim.ai' // optional, defaults to https://api.sim.ai }); // Execute a workflow @@ -43,7 +43,7 @@ new SimStudioClient(config: SimStudioConfig) ``` - `config.apiKey` (string): Your Sim API key -- `config.baseUrl` (string, optional): Base URL for the Sim API (defaults to `https://sim.ai`) +- `config.baseUrl` (string, optional): Base URL for the Sim API (defaults to `https://api.sim.ai`) #### Methods diff --git a/packages/ts-sdk/examples/basic-usage.ts b/packages/ts-sdk/examples/basic-usage.ts index f89b0d0d9..248d41e3c 100644 --- a/packages/ts-sdk/examples/basic-usage.ts +++ b/packages/ts-sdk/examples/basic-usage.ts @@ -4,7 +4,7 @@ import { SimStudioClient, SimStudioError } from '../src/index' async function basicExample() { const client = new SimStudioClient({ apiKey: process.env.SIM_API_KEY!, - baseUrl: 'https://sim.ai', + baseUrl: 'https://api.sim.ai', }) try { diff --git a/packages/ts-sdk/src/index.ts b/packages/ts-sdk/src/index.ts index e6e765786..04476e9de 100644 --- a/packages/ts-sdk/src/index.ts +++ b/packages/ts-sdk/src/index.ts @@ -113,7 +113,7 @@ export class SimStudioClient { constructor(config: SimStudioConfig) { this.apiKey = config.apiKey - this.baseUrl = normalizeBaseUrl(config.baseUrl || 'https://sim.ai') + this.baseUrl = normalizeBaseUrl(config.baseUrl || 'https://api.sim.ai') } /**