Compare commits

..

1 Commits

Author SHA1 Message Date
waleed
2b29c8c258 feat(api): add dedicated api endpoint, update docs, update deploy modal 2026-02-01 20:15:54 -08:00
39 changed files with 92 additions and 60 deletions

View File

@@ -14,7 +14,7 @@ Alle API-Anfragen erfordern einen API-Schlüssel, der im Header `x-api-key` übe
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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. Sie können API-Schlüssel in Ihren Benutzereinstellungen im Sim-Dashboard generieren.
@@ -528,7 +528,7 @@ async function pollLogs() {
} }
const response = await fetch( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -142,7 +142,7 @@ GET /api/users/me/usage-limits
**Beispielanfrage:** **Beispielanfrage:**
```bash ```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:** **Beispielantwort:**

View File

@@ -647,7 +647,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -965,7 +965,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -14,7 +14,7 @@ All API requests require an API key passed in the `x-api-key` header:
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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. You can generate API keys from your user settings in the Sim dashboard.
@@ -513,7 +513,7 @@ async function pollLogs() {
} }
const response = await fetch( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -160,7 +160,7 @@ GET /api/users/me/usage-limits
**Example Request:** **Example Request:**
```bash ```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:** **Example Response:**

View File

@@ -82,7 +82,7 @@ Submit forms programmatically:
<Tabs items={['cURL', 'TypeScript']}> <Tabs items={['cURL', 'TypeScript']}>
<Tab value="cURL"> <Tab value="cURL">
```bash ```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" \ -H "Content-Type: application/json" \
-d '{ -d '{
"formData": { "formData": {
@@ -94,7 +94,7 @@ curl -X POST https://sim.ai/api/form/your-identifier \
</Tab> </Tab>
<Tab value="TypeScript"> <Tab value="TypeScript">
```typescript ```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', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
@@ -115,14 +115,14 @@ const result = await response.json();
For password-protected forms: For password-protected forms:
```bash ```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" \ -H "Content-Type: application/json" \
-d '{ "password": "secret", "formData": { "name": "John" } }' -d '{ "password": "secret", "formData": { "name": "John" } }'
``` ```
For email-protected forms: For email-protected forms:
```bash ```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" \ -H "Content-Type: application/json" \
-d '{ "email": "allowed@example.com", "formData": { "name": "John" } }' -d '{ "email": "allowed@example.com", "formData": { "name": "John" } }'
``` ```

View File

@@ -655,7 +655,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -948,7 +948,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -14,7 +14,7 @@ Todas las solicitudes a la API requieren una clave de API pasada en el encabezad
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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. 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( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -142,7 +142,7 @@ GET /api/users/me/usage-limits
**Solicitud de ejemplo:** **Solicitud de ejemplo:**
```bash ```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:** **Respuesta de ejemplo:**

View File

@@ -656,7 +656,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -965,7 +965,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -14,7 +14,7 @@ Toutes les requêtes API nécessitent une clé API transmise dans l'en-tête `x-
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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. 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( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -142,7 +142,7 @@ GET /api/users/me/usage-limits
**Exemple de requête :** **Exemple de requête :**
```bash ```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 :** **Exemple de réponse :**

View File

@@ -656,7 +656,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -965,7 +965,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -14,7 +14,7 @@ Simは、ワークフローの実行ログを照会したり、ワークフロ
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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キーを生成できます。 SimダッシュボードのユーザーセッティングからAPIキーを生成できます。
@@ -528,7 +528,7 @@ async function pollLogs() {
} }
const response = await fetch( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -142,7 +142,7 @@ GET /api/users/me/usage-limits
**リクエスト例:** **リクエスト例:**
```bash ```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
``` ```
**レスポンス例:** **レスポンス例:**

View File

@@ -656,7 +656,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -965,7 +965,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -14,7 +14,7 @@ Sim 提供了一个全面的外部 API用于查询工作流执行日志
```bash ```bash
curl -H "x-api-key: YOUR_API_KEY" \ 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 密钥。 您可以在 Sim 仪表板的用户设置中生成 API 密钥。
@@ -528,7 +528,7 @@ async function pollLogs() {
} }
const response = await fetch( const response = await fetch(
`https://sim.ai/api/v1/logs?${params}`, `https://api.sim.ai/api/v1/logs?${params}`,
{ {
headers: { headers: {
'x-api-key': 'YOUR_API_KEY' 'x-api-key': 'YOUR_API_KEY'

View File

@@ -142,7 +142,7 @@ GET /api/users/me/usage-limits
**请求示例:** **请求示例:**
```bash ```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
``` ```
**响应示例:** **响应示例:**

View File

@@ -656,7 +656,7 @@ def stream_workflow():
def generate(): def generate():
response = requests.post( response = requests.post(
'https://sim.ai/api/workflows/WORKFLOW_ID/execute', 'https://api.sim.ai/api/workflows/WORKFLOW_ID/execute',
headers={ headers={
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': os.getenv('SIM_API_KEY') 'X-API-Key': os.getenv('SIM_API_KEY')

View File

@@ -965,7 +965,7 @@ function StreamingWorkflow() {
// IMPORTANT: Make this API call from your backend server, not the browser // IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code // 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -16,7 +16,7 @@ import {
ModalTabsList, ModalTabsList,
ModalTabsTrigger, ModalTabsTrigger,
} from '@/components/emcn' } 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 { getInputFormatExample as getInputFormatExampleUtil } from '@/lib/workflows/operations/deployment-utils'
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' 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' 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 return null
} }
const endpoint = `${getBaseUrl()}/api/workflows/${workflowId}/execute` const endpoint = `${getApiUrl()}/api/workflows/${workflowId}/execute`
const inputFormatExample = getInputFormatExample(selectedStreamingOutputs.length > 0) const inputFormatExample = getInputFormatExample(selectedStreamingOutputs.length > 0)
const placeholderKey = getApiHeaderPlaceholder() const placeholderKey = getApiHeaderPlaceholder()

View File

@@ -1,4 +1,5 @@
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { getApiUrl } from '@/lib/core/utils/urls'
import type { ExecutionResult, StreamingExecution } from '@/executor/types' import type { ExecutionResult, StreamingExecution } from '@/executor/types'
import { useExecutionStore } from '@/stores/execution' import { useExecutionStore } from '@/stores/execution'
import { useTerminalConsoleStore } from '@/stores/terminal' import { useTerminalConsoleStore } from '@/stores/terminal'
@@ -41,7 +42,8 @@ export async function executeWorkflowWithFullLogging(
isClientSession: true, isClientSession: true,
} }
const response = await fetch(`/api/workflows/${activeWorkflowId}/execute`, { const apiUrl = getApiUrl()
const response = await fetch(`${apiUrl}/api/workflows/${activeWorkflowId}/execute`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -11,7 +11,7 @@ export const ApiTriggerBlock: BlockConfig = {
bestPractices: ` bestPractices: `
- Can run the workflow manually to test implementation when this is the trigger point. - 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. <api1.paramName>. You can set the value in the input format to test the workflow manually. - The input format determines variables accesssible in the following blocks. E.g. <api1.paramName>. 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', category: 'triggers',
hideFromToolbar: true, hideFromToolbar: true,

View File

@@ -1,5 +1,6 @@
import { useCallback, useRef } from 'react' import { useCallback, useRef } from 'react'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { getApiUrl } from '@/lib/core/utils/urls'
import type { import type {
BlockCompletedData, BlockCompletedData,
BlockErrorData, BlockErrorData,
@@ -151,7 +152,8 @@ export function useExecutionStream() {
currentExecutionRef.current = null currentExecutionRef.current = null
try { try {
const response = await fetch(`/api/workflows/${workflowId}/execute`, { const apiUrl = getApiUrl()
const response = await fetch(`${apiUrl}/api/workflows/${workflowId}/execute`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -211,7 +213,8 @@ export function useExecutionStream() {
currentExecutionRef.current = null currentExecutionRef.current = null
try { 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', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -266,9 +269,13 @@ export function useExecutionStream() {
const cancel = useCallback(() => { const cancel = useCallback(() => {
const execution = currentExecutionRef.current const execution = currentExecutionRef.current
if (execution) { if (execution) {
fetch(`/api/workflows/${execution.workflowId}/executions/${execution.executionId}/cancel`, { const apiUrl = getApiUrl()
method: 'POST', fetch(
}).catch(() => {}) `${apiUrl}/api/workflows/${execution.workflowId}/executions/${execution.executionId}/cancel`,
{
method: 'POST',
}
).catch(() => {})
} }
if (abortControllerRef.current) { if (abortControllerRef.current) {

View File

@@ -5,6 +5,7 @@ import {
type BaseClientToolMetadata, type BaseClientToolMetadata,
ClientToolCallState, ClientToolCallState,
} from '@/lib/copilot/tools/client/base-tool' } from '@/lib/copilot/tools/client/base-tool'
import { getApiUrl } from '@/lib/core/utils/urls'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store' import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
interface CheckDeploymentStatusArgs { interface CheckDeploymentStatusArgs {
@@ -103,11 +104,12 @@ export class CheckDeploymentStatusClientTool extends BaseClientTool {
// API deployment details // API deployment details
const isApiDeployed = apiDeploy?.isDeployed || false const isApiDeployed = apiDeploy?.isDeployed || false
const apiUrl = getApiUrl()
const appUrl = typeof window !== 'undefined' ? window.location.origin : '' const appUrl = typeof window !== 'undefined' ? window.location.origin : ''
const apiDetails: ApiDeploymentDetails = { const apiDetails: ApiDeploymentDetails = {
isDeployed: isApiDeployed, isDeployed: isApiDeployed,
deployedAt: apiDeploy?.deployedAt || null, deployedAt: apiDeploy?.deployedAt || null,
endpoint: isApiDeployed ? `${appUrl}/api/workflows/${workflowId}/execute` : null, endpoint: isApiDeployed ? `${apiUrl}/api/workflows/${workflowId}/execute` : null,
apiKey: apiDeploy?.apiKey || null, apiKey: apiDeploy?.apiKey || null,
needsRedeployment: apiDeploy?.needsRedeployment === true, needsRedeployment: apiDeploy?.needsRedeployment === true,
} }

View File

@@ -6,7 +6,7 @@ import {
ClientToolCallState, ClientToolCallState,
} from '@/lib/copilot/tools/client/base-tool' } from '@/lib/copilot/tools/client/base-tool'
import { registerToolUIConfig } from '@/lib/copilot/tools/client/ui-config' 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 { getInputFormatExample } from '@/lib/workflows/operations/deployment-utils'
import { useCopilotStore } from '@/stores/panel/copilot/store' import { useCopilotStore } from '@/stores/panel/copilot/store'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store' import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
@@ -230,8 +230,8 @@ export class DeployApiClientTool extends BaseClientTool {
} }
if (action === 'deploy') { if (action === 'deploy') {
const appUrl = getBaseUrl() const apiUrl = getApiUrl()
const apiEndpoint = `${appUrl}/api/workflows/${workflowId}/execute` const apiEndpoint = `${apiUrl}/api/workflows/${workflowId}/execute`
const apiKeyPlaceholder = '$SIM_API_KEY' const apiKeyPlaceholder = '$SIM_API_KEY'
const inputExample = getInputFormatExample(false) const inputExample = getInputFormatExample(false)

View File

@@ -307,6 +307,7 @@ export const env = createEnv({
client: { client: {
// Core Application URLs - Required for frontend functionality // 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_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 // Client-side Services
NEXT_PUBLIC_SOCKET_URL: z.string().url().optional(), // WebSocket server URL for real-time features 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: { experimental__runtimeEnv: {
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL, 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_BILLING_ENABLED: process.env.NEXT_PUBLIC_BILLING_ENABLED,
NEXT_PUBLIC_SOCKET_URL: process.env.NEXT_PUBLIC_SOCKET_URL, NEXT_PUBLIC_SOCKET_URL: process.env.NEXT_PUBLIC_SOCKET_URL,
NEXT_PUBLIC_BRAND_NAME: process.env.NEXT_PUBLIC_BRAND_NAME, NEXT_PUBLIC_BRAND_NAME: process.env.NEXT_PUBLIC_BRAND_NAME,

View File

@@ -54,3 +54,22 @@ export function getEmailDomain(): string {
return isProd ? 'sim.ai' : 'localhost:3000' 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()
}

View File

@@ -17,7 +17,7 @@ from simstudio import SimStudioClient
# Initialize the client # Initialize the client
client = SimStudioClient( client = SimStudioClient(
api_key=os.getenv("SIM_API_KEY", "your-api-key-here"), 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 # Execute a workflow
@@ -35,11 +35,11 @@ except Exception as error:
#### Constructor #### Constructor
```python ```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 - `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 #### Methods
@@ -364,7 +364,7 @@ from simstudio import SimStudioClient
# Using environment variables # Using environment variables
client = SimStudioClient( client = SimStudioClient(
api_key=os.getenv("SIM_API_KEY"), 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")
) )
``` ```

View File

@@ -87,10 +87,10 @@ class SimStudioClient:
Args: Args:
api_key: Your Sim API key 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.api_key = api_key
self.base_url = base_url.rstrip('/') self.base_url = base_url.rstrip('/')
self._session = requests.Session() self._session = requests.Session()

View File

@@ -18,7 +18,7 @@ def test_simstudio_client_default_base_url():
"""Test SimStudioClient with default base URL.""" """Test SimStudioClient with default base URL."""
client = SimStudioClient(api_key="test-api-key") client = SimStudioClient(api_key="test-api-key")
assert client.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(): 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") result = client.validate_workflow("test-workflow-id")
assert result is False 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(): def test_simstudio_error():

View File

@@ -20,7 +20,7 @@ import { SimStudioClient } from 'simstudio-ts-sdk';
// Initialize the client // Initialize the client
const client = new SimStudioClient({ const client = new SimStudioClient({
apiKey: 'your-api-key-here', 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 // Execute a workflow
@@ -43,7 +43,7 @@ new SimStudioClient(config: SimStudioConfig)
``` ```
- `config.apiKey` (string): Your Sim API key - `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 #### Methods

View File

@@ -4,7 +4,7 @@ import { SimStudioClient, SimStudioError } from '../src/index'
async function basicExample() { async function basicExample() {
const client = new SimStudioClient({ const client = new SimStudioClient({
apiKey: process.env.SIM_API_KEY!, apiKey: process.env.SIM_API_KEY!,
baseUrl: 'https://sim.ai', baseUrl: 'https://api.sim.ai',
}) })
try { try {

View File

@@ -113,7 +113,7 @@ export class SimStudioClient {
constructor(config: SimStudioConfig) { constructor(config: SimStudioConfig) {
this.apiKey = config.apiKey this.apiKey = config.apiKey
this.baseUrl = normalizeBaseUrl(config.baseUrl || 'https://sim.ai') this.baseUrl = normalizeBaseUrl(config.baseUrl || 'https://api.sim.ai')
} }
/** /**