Audin Docs
API REST (partner)

Flussi operativi

Tre flussi end-to-end con l'API REST partner — apertura opportunità, invio preventivo e tracking della firma di un contratto.

Versione Markdown di questa pagina

Scarica o copia il contenuto di questa pagina in formato .md — utile per fornirlo a un agente AI che integra questa specifica feature.

Scarica .md

Questa pagina mette in fila le risorse delle guide precedenti in tre flussi end-to-end, così come li affronterebbe un'integrazione server-to-server: dalla nascita di un'opportunità all'invio di un preventivo, fino al tracking della firma di un contratto.

Tutti gli esempi usano l'host https://api.audin.ai e l'header X-API-Key. Per i campi completi di ogni risorsa fai riferimento alle guide per gruppo e allo Swagger.

Flusso 1 — Apertura di un'opportunità

Obiettivo: creare un'azienda, un lead di contatto e aprire una deal nella pipeline di vendita.

Crea l'azienda con POST /companies e conserva l'id ritornato.

Crea il lead con POST /leads, associandolo all'azienda via companyId.

Recupera la pipeline di tipo DEAL (GET /pipelines?type=DEAL) e il suo primo stage.

Crea la deal con POST /deals, indicando pipelineId, stageId e — per collegare i protagonisti — primaryContactId, companyIds e contactIds.

BASE="https://api.audin.ai"

# 1. Crea l'azienda
COMPANY_ID=$(curl -sX POST $BASE/companies \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Srl","domain":"acme.example.com"}' \
  | jq -r '.id')

# 2. Crea il lead associato
LEAD_ID=$(curl -sX POST $BASE/leads \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"fullName\": \"Mario Rossi\",
    \"email\": \"mario@acme.example.com\",
    \"phoneNumber\": \"+393331234567\",
    \"companyId\": \"$COMPANY_ID\"
  }" | jq -r '.id')

# 3. Recupera pipeline DEAL e primo stage
PIPELINES=$(curl -s "$BASE/pipelines?type=DEAL" \
  -H "X-API-Key: $API_KEY")
PIPELINE_ID=$(echo "$PIPELINES" | jq -r '.[0].id')
STAGE_ID=$(echo "$PIPELINES" | jq -r '.[0].stages[0].id')

# 4. Crea la deal collegata a lead e azienda
curl -X POST $BASE/deals \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"title\": \"Opportunità Acme\",
    \"pipelineId\": \"$PIPELINE_ID\",
    \"stageId\": \"$STAGE_ID\",
    \"amount\": 5000,
    \"currency\": \"EUR\",
    \"primaryContactId\": \"$LEAD_ID\",
    \"companyIds\": [\"$COMPANY_ID\"],
    \"contactIds\": [\"$LEAD_ID\"]
  }"
const BASE = "https://api.audin.ai";
const headers = {
  "X-API-Key": process.env.AUDIN_API_KEY,
  "Content-Type": "application/json",
};

// 1. Crea l'azienda
const company = await (
  await fetch(`${BASE}/companies`, {
    method: "POST",
    headers,
    body: JSON.stringify({ name: "Acme Srl", domain: "acme.example.com" }),
  })
).json();

// 2. Crea il lead associato
const lead = await (
  await fetch(`${BASE}/leads`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      fullName: "Mario Rossi",
      email: "mario@acme.example.com",
      phoneNumber: "+393331234567",
      companyId: company.id,
    }),
  })
).json();

// 3. Recupera pipeline DEAL e primo stage
const pipelines = await (
  await fetch(`${BASE}/pipelines?type=DEAL`, { headers })
).json();
const { id: pipelineId, stages } = pipelines[0];

// 4. Crea la deal collegata a lead e azienda
const deal = await (
  await fetch(`${BASE}/deals`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      title: "Opportunità Acme",
      pipelineId,
      stageId: stages[0].id,
      amount: 5000,
      currency: "EUR",
      primaryContactId: lead.id,
      companyIds: [company.id],
      contactIds: [lead.id],
    }),
  })
).json();

Vedi CRM anagrafiche per i campi di lead e aziende e Pipeline & deal per quelli della deal.

Flusso 2 — Invio di un preventivo

Obiettivo: generare un preventivo da un template e recapitarlo al contatto della deal. Il preventivo eredita le righe prodotto dalla deal: non si passa una lista di articoli alla creazione, ma dealId + templateId.

Elenca i template di tipo QUOTE (GET /document-templates?type=QUOTE) e scegline uno.

Crea il preventivo con POST /quotes passando dealId e templateId (opzionalmente clauseIds ed expiresAt).

Invialo con POST /quotes/{id}/send: Audin genera il documento e lo recapita al contatto della deal.

BASE="https://api.audin.ai"

# 1. Scegli un template QUOTE (la lista è paginata: { templates, total, … })
TEMPLATE_ID=$(curl -s "$BASE/document-templates?type=QUOTE" \
  -H "X-API-Key: $API_KEY" | jq -r '.templates[0].id')

# 2. Crea il preventivo dalla deal
QUOTE_ID=$(curl -sX POST $BASE/quotes \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"dealId\":\"<deal-id>\",\"templateId\":\"$TEMPLATE_ID\"}" \
  | jq -r '.id')

# 3. Invialo al cliente
curl -X POST "$BASE/quotes/$QUOTE_ID/send" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const BASE = "https://api.audin.ai";
const headers = {
  "X-API-Key": process.env.AUDIN_API_KEY,
  "Content-Type": "application/json",
};

// 1. Scegli un template QUOTE (la lista è paginata: { templates, total, … })
const templates = await (
  await fetch(`${BASE}/document-templates?type=QUOTE`, { headers })
).json();
const templateId = templates.templates[0].id;

// 2. Crea il preventivo dalla deal
const quote = await (
  await fetch(`${BASE}/quotes`, {
    method: "POST",
    headers,
    body: JSON.stringify({ dealId, templateId }),
  })
).json();

// 3. Invialo al cliente
await fetch(`${BASE}/quotes/${quote.id}/send`, {
  method: "POST",
  headers,
  body: JSON.stringify({}),
});

Lo stato di un preventivo (DRAFT, SENT, VIEWED, ACCEPTED, REJECTED, EXPIRED) si legge con GET /quotes/{id}. Vedi Documenti.

Flusso 3 — Tracking della firma di un contratto

Obiettivo: inviare un contratto per la firma e seguirne l'evoluzione fino a uno stato finale. Non esistono webhook: lo stato si segue con polling periodico di GET /contracts/{id}, leggendo il campo .status.

Gli stati di un contratto:

StatoSignificato
DRAFTBozza, non ancora inviato
SENTInviato al firmatario
VIEWEDVisualizzato dal firmatario
SIGNEDFirmato (stato finale positivo)
REJECTEDRifiutato dal firmatario
EXPIREDScaduto senza firma

Crea il contratto con POST /contracts (dealId + templateId).

Invialo per la firma con POST /contracts/{id}/send.

Esegui il polling di GET /contracts/{id} a intervalli regolari, leggendo .status, finché non raggiungi uno stato finale (SIGNED, REJECTED, EXPIRED).

BASE="https://api.audin.ai"

# 1. Crea e 2. invia il contratto per la firma
CONTRACT_ID=$(curl -sX POST $BASE/contracts \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dealId":"<deal-id>","templateId":"<contract-template-id>"}' \
  | jq -r '.id')

curl -X POST "$BASE/contracts/$CONTRACT_ID/send" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

# 3. Polling dello stato (no webhook)
while true; do
  STATUS=$(curl -s "$BASE/contracts/$CONTRACT_ID" \
    -H "X-API-Key: $API_KEY" | jq -r '.status')
  echo "[$(date)] Status: $STATUS"

  case "$STATUS" in
    SIGNED|REJECTED|EXPIRED)
      echo "Stato finale raggiunto: $STATUS"
      break
      ;;
  esac

  sleep 60
done
const BASE = "https://api.audin.ai";
const headers = {
  "X-API-Key": process.env.AUDIN_API_KEY,
  "Content-Type": "application/json",
};

// 1. Crea e 2. invia il contratto per la firma
const contract = await (
  await fetch(`${BASE}/contracts`, {
    method: "POST",
    headers,
    body: JSON.stringify({ dealId, templateId: contractTemplateId }),
  })
).json();

await fetch(`${BASE}/contracts/${contract.id}/send`, {
  method: "POST",
  headers,
  body: JSON.stringify({}),
});

// 3. Polling dello stato (no webhook)
const FINAL = new Set(["SIGNED", "REJECTED", "EXPIRED"]);

async function pollStatus() {
  while (true) {
    const current = await (
      await fetch(`${BASE}/contracts/${contract.id}`, {
        headers: { "X-API-Key": process.env.AUDIN_API_KEY },
      })
    ).json();

    if (FINAL.has(current.status)) return current.status;
    await new Promise((r) => setTimeout(r, 60_000)); // attendi 60s
  }
}

const finalStatus = await pollStatus();

L'API è polling-only: non ci sono webhook. Per gli stati che evolvono nel tempo (firma di un contratto, accettazione di un preventivo) interroga la risorsa a intervalli regolari (es. ogni 60s). Tieni conto del rate limit (100 req/min per API Key) quando scegli la frequenza di polling.

Prossimo passo

On this page