Integrate Project into Your App
Connect your Triform Project to external applications via API
Overview
Once you've built and tested a Project in Triform, you'll want to integrate it into your application. This tutorial covers API integration, authentication, and best practices.
Time required: 20-30 minutes
Prerequisites
- A deployed Triform Project
- API key for authentication
- Basic knowledge of HTTP requests
Step 1: Deploy your Project
Before integrating, deploy your Project:
Open your Project on the Canvas
Click Deploy in the Top Bar
Select the target environment (staging or production)
Configure the deployment:
- Endpoint name: Choose a memorable name (e.g.,
news-digest) - HTTP method: POST (most common) or GET
- Authentication: API key required (recommended)
- Endpoint name: Choose a memorable name (e.g.,
Click Deploy Now
Copy the generated endpoint URL:
https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784
Step 2: Generate an API key
- Go to Profile → API Keys
- Click Create New Key
- Name it:
Production Integration - Set permissions: Execute Projects
- Copy the key (shown only once!)
- Store securely (use environment variables)
Security note: Never commit API keys to version control. Use environment variables or secret managers.
Step 3: Make your first API call
Using cURL
This is an API-call that would trigger a certain flow with the {"sources": ["https://newsapi.org/v2/top-headlines?country=us", "https://api.example.com/tech-news"]} payload:
curl -X POST 'https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784' \ --header 'Authorization: 88ffe8398f972837ccc6e0a6cd31c5c92689040c' \ --header 'Content-Type: application/json' \ --data '{"sources": ["https://newsapi.org/v2/top-headlines?country=us", "https://api.example.com/tech-news"]}'Using Python
import requestsimport osAPI_KEY = os.environ.get('TRIFORM_API_KEY')ENDPOINT = 'https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784'headers = { 'Authorization': API_KEY, 'Content-Type': 'application/json'}payload = { 'sources': [ 'https://newsapi.org/v2/top-headlines?country=us', 'https://api.example.com/tech-news' ]}response = requests.post(ENDPOINT, json=payload, headers=headers)if response.status_code == 200: result = response.json() print('Success:', result)else: print('Error:', response.status_code, response.text)Using JavaScript (Node.js)
const axios = require('axios');const API_KEY = process.env.TRIFORM_API_KEY;const ENDPOINT = 'https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784';const headers = { 'Authorization': API_KEY, 'Content-Type': 'application/json'};const payload = { sources: [ 'https://newsapi.org/v2/top-headlines?country=us', 'https://api.example.com/tech-news' ]};axios.post(ENDPOINT, payload, { headers }) .then(response => { console.log('Success:', response.data); }) .catch(error => { console.error('Error:', error.response?.status, error.response?.data); });Using JavaScript (Browser/React)
const callTriformAPI = async () => { const API_KEY = process.env.REACT_APP_TRIFORM_API_KEY; const ENDPOINT = 'https://app.triform.ai/api/in/31460071-17aa-43e8-a0e6-fb22984c0bdc/26420f15-2143-443f-bca9-45c5b0720784'; try { const response = await fetch(ENDPOINT, { method: 'POST', headers: { 'Authorization': API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ sources: [ 'https://newsapi.org/v2/top-headlines?country=us', 'https://api.example.com/tech-news' ] }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log('Success:', data); return data; } catch (error) { console.error('Error:', error); }};Step 4: Handle responses
Triform API responses follow this structure:
Success response (200 OK)
{ "execution_id": "exec_abc123", "status": "completed", "output": { "digest": "Top stories today include...", "article_count": 42, "topics": ["technology", "politics", "science"] }, "execution_time_ms": 3420, "timestamp": "2025-10-01T10:30:00Z"}Error response (4xx/5xx)
{ "error": { "code": "invalid_input", "message": "Field 'sources' is required", "details": { "field": "sources", "expected_type": "array" } }, "request_id": "req_xyz789"}Handling in code
def call_triform_api(payload): response = requests.post(ENDPOINT, json=payload, headers=headers) if response.status_code == 200: data = response.json() return { 'success': True, 'data': data['output'], 'execution_id': data['execution_id'] } elif response.status_code == 400: error = response.json()['error'] return { 'success': False, 'error': error['message'], 'code': error['code'] } elif response.status_code == 429: # Rate limit exceeded return { 'success': False, 'error': 'Rate limit exceeded. Try again later.' } elif response.status_code >= 500: # Server error return { 'success': False, 'error': 'Triform service temporarily unavailable' } else: return { 'success': False, 'error': f'Unexpected error: {response.status_code}' }Step 5: Implement error handling
Retry logic with exponential backoff
import timefrom typing import Optionaldef call_with_retry(payload, max_retries=3): for attempt in range(max_retries): try: response = requests.post( ENDPOINT, json=payload, headers=headers, timeout=30 ) if response.status_code == 200: return response.json() elif response.status_code == 429: # Rate limited, wait and retry wait_time = 2 ** attempt # 1s, 2s, 4s time.sleep(wait_time) continue elif response.status_code >= 500: # Server error, retry wait_time = 2 ** attempt time.sleep(wait_time) continue else: # Client error, don't retry raise Exception(f"API error: {response.text}") except requests.exceptions.Timeout: if attempt < max_retries - 1: time.sleep(2 ** attempt) continue raise except requests.exceptions.RequestException as e: if attempt < max_retries - 1: time.sleep(2 ** attempt) continue raise raise Exception(f"Failed after {max_retries} attempts")Timeout handling
Always set timeouts to prevent hanging requests:
# Set reasonable timeout (connect timeout, read timeout)response = requests.post( ENDPOINT, json=payload, headers=headers, timeout=(5, 30) # 5s to connect, 30s to read)Step 6: Integrate into your application
Example: Web dashboard
# Flask appfrom flask import Flask, render_template, request, jsonifyapp = Flask(__name__)@app.route('/dashboard')def dashboard(): return render_template('dashboard.html')@app.route('/api/refresh-news', methods=['POST'])def refresh_news(): sources = request.json.get('sources', []) result = call_triform_api({ 'sources': sources }) if result['success']: return jsonify({ 'digest': result['data']['digest'], 'article_count': result['data']['article_count'] }) else: return jsonify({'error': result['error']}), 400Example: Scheduled job
# Daily cron jobimport scheduleimport timedef fetch_daily_news(): print("Fetching daily news digest...") payload = { 'sources': [ 'https://newsapi.org/v2/top-headlines?country=us', 'https://api.example.com/tech-news' ] } result = call_with_retry(payload) # Save to database or send email save_to_database(result['output']['digest']) send_email_digest(result['output']['digest']) print("Daily news digest completed")# Schedule for 6 AM dailyschedule.every().day.at("06:00").do(fetch_daily_news)while True: schedule.run_pending() time.sleep(60)Example: Real-time processing
# Process incoming webhooksfrom fastapi import FastAPI, BackgroundTasksapp = FastAPI()@app.post('/webhook/new-content')async def handle_new_content(data: dict, background_tasks: BackgroundTasks): # Trigger Triform processing in background background_tasks.add_task(process_with_triform, data) return {'status': 'processing'}def process_with_triform(data): result = call_triform_api({ 'content': data['content'], 'metadata': data['metadata'] }) # Store results store_results(result)Step 7: Monitor and optimize
Track API usage
import logginglogger = logging.getLogger(__name__)def call_triform_api_with_logging(payload): start_time = time.time() try: response = requests.post(ENDPOINT, json=payload, headers=headers) elapsed = time.time() - start_time logger.info(f"Triform API call completed in {elapsed:.2f}s, status: {response.status_code}") return response.json() except Exception as e: elapsed = time.time() - start_time logger.error(f"Triform API call failed after {elapsed:.2f}s: {str(e)}") raiseCaching results
from functools import lru_cacheimport hashlibimport json# Simple in-memory cachecache = {}CACHE_TTL = 3600 # 1 hourdef get_cache_key(payload): return hashlib.md5(json.dumps(payload, sort_keys=True).encode()).hexdigest()def call_triform_cached(payload): cache_key = get_cache_key(payload) # Check cache if cache_key in cache: cached_data, timestamp = cache[cache_key] if time.time() - timestamp < CACHE_TTL: logger.info("Returning cached result") return cached_data # Call API result = call_triform_api(payload) # Store in cache cache[cache_key] = (result, time.time()) return resultBest practices
Use environment variables — Never hardcode API keys
Implement retries — Network issues happen; retry with backoff
Set timeouts — Don't let requests hang indefinitely
Log everything — Track success/failure for debugging
Cache when appropriate — Save API calls for expensive operations
Monitor quota — Track usage against your plan limits
Test error paths — Ensure your app handles API failures gracefully
Version your integration — Track which API version you're using
Troubleshooting
Problem: 401 UnauthorizedSolution: Check API key is correct and has Execute permissions
Problem: 429 Too Many RequestsSolution: Implement rate limiting, add delays between requests
Problem: 500 Server ErrorSolution: Retry with backoff, check Triform status page
Problem: Slow responsesSolution: Optimize your Project, add caching, use async requests
Problem: Unexpected output formatSolution: Verify Project schema matches your expectations, check docs
Next steps
Continue exploring the documentation to learn about deployments, API key management, monitoring, quotas, and security best practices.
Was this helpful?
More in Tutorials
Build a New ProjectEdit an Existing ProjectStill need help? Ask the team