Skip to Content
🚀 Discko v2.0 is now available!

API

Integrate with Discko programmatically using our REST API.

Getting Started

Step 1: Create an API key

  1. Log in to your Discko dashboard.
  2. Go to Mise en place > CRM.
  3. Expand “REST API”.
  4. Create a new key and copy it somewhere safe. You will use it to authenticate every request.

Step 2: Make an authenticated request

Send your API key in the X-Discko-Key header.

curl -X GET "https://app.discko.io/api/v1/leads" -H "X-Discko-Key: <YOUR_API_KEY>"
// Example in Node.js / browser const API_URL = "https://app.discko.io/api/v1"; async function listLeads() { const response = await fetch(`${API_URL}/leads`, { headers: { "X-Discko-Key": process.env.DISCKO_API_KEY } }); if (!response.ok) throw new Error(`Request failed: ${response.status}`); return response.json(); }

How it works

  • Base URL: https://app.discko.io/api/v1
  • Authentication: X-Discko-Key: <YOUR_API_KEY> on every request
  • Dates: All timestamps use ISO 8601 (UTC), for example 2024-01-15T10:30:00Z

Breaking Changes

2025-12-22 - Finished Leads Only (FT05)

Type: Breaking change mineur

Behavior: All API endpoints now return only completed leads (where the user has seen the Discko-generated summary). Leads that are still in progress (not yet finished) are no longer accessible via the API.

Affected endpoints:

  • GET /api/v1/leads - Only returns finished leads
  • GET /api/v1/leads/{id} - Returns 404 if the lead is not finished
  • PUT /api/v1/leads/{id} - Returns 404 if the lead is not finished
  • POST /api/make-webhook - Returns 404 if the lead is not finished

Impact: Clients that were retrieving all leads (including incomplete ones) will no longer receive them. This change improves the quality of data received.

Migration: No client-side action required. All leads returned by the API are guaranteed to be complete with full analysis and summary data.


2025-12-18 - Standardized Error Format

All API endpoints now return a standardized response format for both success and error cases.

Success Response Format:

{ "success": true, "data": [...] }

Error Response Format:

{ "success": false, "error": { "code": "UNAUTHORIZED", "message": "API key is missing or invalid.", "details": null }, "timestamp": "2025-12-18T10:30:00Z" }

Available Error Codes:

CodeHTTP StatusDescription
UNAUTHORIZED401API key is missing or invalid.
FORBIDDEN403Access denied to this resource.
LEAD_NOT_FOUND404The requested lead does not exist or is not yet finished.
VALIDATION_ERROR400Request validation failed.
INVALID_JSON400Request body is not valid JSON.
INVALID_STATUS400Status must be one of: NEW, IN_PROGRESS, WON, LOST.
INTERNAL_ERROR500An unexpected error occurred.

Migration Guide:

Existing integrations must update their error parsing:

  • Before: response.error (string)
  • After: response.error.code (string) + response.error.message (string)

The success boolean field allows you to quickly distinguish success from error responses.

Endpoints

Leads

GET /api/v1/leads

Returns the list of leads collected from your forms.

Note importante : L’API ne retourne que les leads ayant complété le formulaire Discko. Les leads en cours de complétion ne sont pas accessibles via l’API. Un lead est considéré comme “terminé” lorsque l’utilisateur a vu la synthèse générée par Discko.

curl -H "X-Discko-Key: <YOUR_API_KEY>" "https://app.discko.io/api/v1/leads"
{ "success": true, "data": [ { "id": "req_abc123", "locked": false, "url": "https://app.discko.io/acme/leads/req_abc123", "date": "2025-08-05T08:30:00.000Z", "status": "NEW", "completion": 100, "category": "Web Development", "contact": { "type": "COMPANY", "firstName": "Jane", "lastName": "Smith", "email": "user@example.com", "phone": "+1234567890", "linkedin": "https://linkedin.com/in/janesmith", "jobTitle": "CEO", "discProfile": "Dominant", "discProfileExplanation": "The communication style is direct, concise, and assertive. The prospect doesn’t elaborate, gets straight to the point, and delivers their message clearly and without ambiguity" }, "company": { "name": "Example Corp", "address": "123 Business St, New York, NY", "website": "https://example.com" }, "analysis": { "fitScore": 2, "fitScoreExplanation": "The prospect wants to purchase a service that perfectly matches your offer. The answers are consistent, and no blocking constraints have been identified. → Score 2.", "intentScore": 2, "intentScoreExplanation": "The prospect expresses a clear and mature intention, has defined a budget, faces no technical obstacles, and provides precise answers. They are therefore genuinely in the purchasing stage and looking to move forward. → Score 2", "budget": "10000-15000", "budgetExplanation": "Budget aligns well with scope", "deadline": "2025-09-15T00:00:00.000Z", "deadlineExplanation": "Project needs to be completed before Q4", "score": 7 }, "summary": { "abstract": "High-value lead with strong fit and intent", "needs": "Modern website with e-commerce", "comment": "Looking for quick turnaround", "categories": [ { "name": "Technical Requirements", "description": "Core technical specifications for the project", "summary": [ "E-commerce platform integration", "Mobile-responsive design", "Payment gateway setup" ] }, { "name": "Business Goals", "description": "Key business objectives", "summary": [ "Increase online sales", "Improve customer experience", "Launch before Q4" ] } ] } } ] }

GET /api/v1/leads/:id

Returns a single lead by ID with full details.

Note importante : L’API ne retourne que les leads ayant complété le formulaire Discko. Les leads en cours de complétion ne sont pas accessibles via l’API. Un lead est considéré comme “terminé” lorsque l’utilisateur a vu la synthèse générée par Discko.

curl -H "X-Discko-Key: <YOUR_API_KEY>" "https://app.discko.io/api/v1/leads/req_abc123"
{ "success": true, "data": { "id": "req_abc123", "locked": false, "url": "https://app.discko.io/acme/leads/req_abc123", "date": "2025-08-27T12:44:38.712Z", "status": "NEW", "completion": 100, "category": "Digital Marketing", "contact": { "type": "PERSON", "firstName": "Alex", "lastName": "Doe", "email": "alex.doe@email.com", "phone": "+1234567890", "address": "456 Main St, Los Angeles, CA", "discProfile": "Steady", "discProfileExplanation": "The communication style is direct, concise, and assertive. The prospect doesn’t elaborate, gets straight to the point, and delivers their message clearly and without ambiguity" }, "company": null, "analysis": { "fitScore": 1, "fitScoreExplanation": "The prospect wants to purchase a service that perfectly matches your offer. The answers are consistent, and no blocking constraints have been identified. → Score 2.", "intentScore": 2, "intentScoreExplanation": "The prospect expresses a clear and mature intention, has defined a budget, faces no technical obstacles, and provides precise answers. They are therefore genuinely in the purchasing stage and looking to move forward. → Score 2", "budget": "5000-10000", "budgetExplanation": "Budget is appropriate for the scope of work", "deadline": "2025-09-27T00:00:00.000Z", "deadlineExplanation": "Needs to start within 30 days", "score": 5 }, "summary": { "abstract": "Qualified lead with clear needs and realistic timeline", "needs": "Comprehensive digital marketing strategy including SEO and content marketing", "comment": "Previous experience with digital marketing agencies", "categories": [ { "name": "SEO Strategy", "description": "Search engine optimization requirements", "summary": [ "Keyword research and optimization", "Technical SEO improvements", "Local SEO focus" ] }, { "name": "Content Marketing", "description": "Content creation and distribution needs", "summary": [ "Blog content strategy", "Social media content calendar", "Email marketing campaigns" ] } ] } } }

Error Response Example

{ "success": false, "error": { "code": "LEAD_NOT_FOUND", "message": "Lead not found", "details": { "lead_id": "req_abc123" } }, "timestamp": "2025-12-18T10:30:00Z" }

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401API key is missing or invalid.
LEAD_NOT_FOUND404The requested lead does not exist or is not yet finished.

PUT /api/v1/leads/:id

Update a lead’s status.

Note importante : L’API ne retourne que les leads ayant complété le formulaire Discko. Les leads en cours de complétion ne sont pas accessibles via l’API. Un lead est considéré comme “terminé” lorsque l’utilisateur a vu la synthèse générée par Discko.

Request Body

FieldTypeRequiredDescription
statusStringYesLead status: "NEW", "IN_PROGRESS", "WON", or "LOST"

Example Request

curl -X PUT "https://app.discko.io/api/v1/leads/req_abc123" \ -H "X-Discko-Key: <YOUR_API_KEY>" \ -H "Content-Type: application/json" \ -d '{"status": "IN_PROGRESS"}'
const API_URL = "https://app.discko.io/api/v1"; async function updateLeadStatus(leadId, status) { const response = await fetch(`${API_URL}/leads/${leadId}`, { method: 'PUT', headers: { "X-Discko-Key": process.env.DISCKO_API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ status }) }); if (!response.ok) { throw new Error(`Request failed: ${response.status}`); } return response.json(); } // Usage await updateLeadStatus('req_abc123', 'IN_PROGRESS');

Response

Returns the updated lead object with the same structure as GET /api/v1/leads/:id.

{ "success": true, "data": { "id": "req_abc123", "locked": false, "url": "https://app.discko.io/acme/leads/req_abc123", "date": "2025-08-27T12:44:38.712Z", "status": "IN_PROGRESS", "completion": 100, "category": "Digital Marketing", "contact": { "type": "PERSON", "firstName": "Alex", "lastName": "Doe", "email": "alex.doe@email.com", "phone": "+1234567890", "address": "456 Main St, Los Angeles, CA", "discProfile": "Steady", "discProfileExplanation": "The communication style is direct, concise, and assertive. The prospect doesn't elaborate, gets straight to the point, and delivers their message clearly and without ambiguity" }, "company": null, "analysis": { "fitScore": 1, "fitScoreExplanation": "The prospect wants to purchase a service that perfectly matches your offer. The answers are consistent, and no blocking constraints have been identified. → Score 2.", "intentScore": 2, "intentScoreExplanation": "The prospect expresses a clear and mature intention, has defined a budget, faces no technical obstacles, and provides precise answers. They are therefore genuinely in the purchasing stage and looking to move forward. → Score 2", "budget": "5000-10000", "budgetExplanation": "Budget is appropriate for the scope of work", "deadline": "2025-09-27T00:00:00.000Z", "deadlineExplanation": "Needs to start within 30 days", "score": 5 }, "summary": { "abstract": "Qualified lead with clear needs and realistic timeline", "needs": "Comprehensive digital marketing strategy including SEO and content marketing", "comment": "Previous experience with digital marketing agencies", "categories": [ { "name": "SEO Strategy", "description": "Search engine optimization requirements", "summary": [ "Keyword research and optimization", "Technical SEO improvements", "Local SEO focus" ] }, { "name": "Content Marketing", "description": "Content creation and distribution needs", "summary": [ "Blog content strategy", "Social media content calendar", "Email marketing campaigns" ] } ] } } }

Error Response Examples

Invalid status value:

{ "success": false, "error": { "code": "INVALID_STATUS", "message": "Status must be one of: NEW, IN_PROGRESS, WON, LOST.", "details": { "provided": "INVALID_VALUE", "allowed": ["NEW", "IN_PROGRESS", "WON", "LOST"] } }, "timestamp": "2025-12-18T10:30:00Z" }

Invalid JSON:

{ "success": false, "error": { "code": "INVALID_JSON", "message": "Request body is not valid JSON.", "details": null }, "timestamp": "2025-12-18T10:30:00Z" }

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401API key is missing or invalid.
LEAD_NOT_FOUND404The requested lead does not exist or is not yet finished.
INVALID_JSON400Request body is not valid JSON.
INVALID_STATUS400Status must be one of: NEW, IN_PROGRESS, WON, LOST.
VALIDATION_ERROR400Request validation failed.

Format de réponse (LeadExternal)

Le format de réponse pour les endpoints GET /api/v1/leads, GET /api/v1/leads/:id et PUT /api/v1/leads/:id retourne un objet data suivant le schéma ci-dessous.

{ "success": true, "data": { "id": "uuid", "locked": false, "url": "https://app.discko.io/{organizationSlug}/leads/{leadId}", "contact": { "type": "PERSON | COMPANY", "firstName": "string", "lastName": "string", "email": "string", "phone": "string", "address": "string (si PERSON)", "linkedin": "string (si COMPANY)", "jobTitle": "string (si COMPANY)", "discProfile": "string | null", "discProfileExplanation": "string | null" }, "company": { "name": "string", "address": "string", "website": "string" }, "analysis": { "fitScore": 0, "fitScoreExplanation": "string", "intentScore": 0, "intentScoreExplanation": "string", "budget": "string | null", "budgetExplanation": "string | null", "deadline": "string | null", "deadlineExplanation": "string | null", "score": 0 }, "summary": { "abstract": "string", "categories": [{ "name": "string", "description": "string", "summary": ["string"] }], "needs": "string", "comment": "string | null" }, "date": "ISO timestamp", "status": "NEW | IN_PROGRESS | WON | LOST", "completion": 0, "category": "string" } }
Last updated on