Zum Hauptinhalt springen
GET
/
public
/
offers
/
{id}
Öffentliches Angebot abrufen
curl --request GET \
  --url https://coreapi.io/public/offers/{id}
{
  "name": "<string>",
  "id": "<string>",
  "number": "<string>",
  "recipientId": "<string>",
  "startDate": "<string>",
  "signedAt": "2021-01-01T00:00:00+00:00",
  "acceptanceMode": "click",
  "status": "open",
  "isPreview": true,
  "validUntil": "2021-01-01T00:00:00+00:00",
  "dealType": "new_business",
  "contractValue": {
    "amountCents": 123,
    "currency": "<string>",
    "interval": "<string>"
  },
  "termLabel": "<string>",
  "proposal": {
    "hasContent": true,
    "currency": "<string>",
    "multiPhase": true,
    "phases": [
      {
        "start": "<string>",
        "end": "<string>",
        "periodLabel": "<string>",
        "name": "<string>",
        "lines": [
          {
            "name": "<string>",
            "description": "<string>",
            "quantityLabel": "<string>",
            "isFlatFee": true,
            "isOneTime": true,
            "unitPrice": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            },
            "intervalLabel": "<string>",
            "originalAmount": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            },
            "amount": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            },
            "hasDiscount": true,
            "discountLabel": "<string>",
            "pricingModel": "<string>",
            "pricingModelLabel": "<string>",
            "pricingModelHint": "<string>",
            "tierPriceLabel": "<string>",
            "hasTierFlatFee": true,
            "tiers": [
              {
                "rangeLabel": "<string>",
                "unitPrice": {
                  "amount": 123,
                  "precision": 123,
                  "currencyCode": "<string>",
                  "formatted": "<string>"
                },
                "flatFee": {
                  "amount": 123,
                  "precision": 123,
                  "currencyCode": "<string>",
                  "formatted": "<string>"
                }
              }
            ]
          }
        ],
        "subtotals": [
          {
            "label": "<string>",
            "amount": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            }
          }
        ],
        "tcv": {
          "amount": 123,
          "precision": 123,
          "currencyCode": "<string>",
          "formatted": "<string>"
        }
      }
    ],
    "oneTime": [
      {
        "name": "<string>",
        "description": "<string>",
        "quantityLabel": "<string>",
        "isFlatFee": true,
        "isOneTime": true,
        "unitPrice": {
          "amount": 123,
          "precision": 123,
          "currencyCode": "<string>",
          "formatted": "<string>"
        },
        "intervalLabel": "<string>",
        "originalAmount": {
          "amount": 123,
          "precision": 123,
          "currencyCode": "<string>",
          "formatted": "<string>"
        },
        "amount": {
          "amount": 123,
          "precision": 123,
          "currencyCode": "<string>",
          "formatted": "<string>"
        },
        "hasDiscount": true,
        "discountLabel": "<string>",
        "pricingModel": "<string>",
        "pricingModelLabel": "<string>",
        "pricingModelHint": "<string>",
        "tierPriceLabel": "<string>",
        "hasTierFlatFee": true,
        "tiers": [
          {
            "rangeLabel": "<string>",
            "unitPrice": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            },
            "flatFee": {
              "amount": 123,
              "precision": 123,
              "currencyCode": "<string>",
              "formatted": "<string>"
            }
          }
        ]
      }
    ],
    "oneTimeTotal": {
      "amount": 123,
      "precision": 123,
      "currencyCode": "<string>",
      "formatted": "<string>"
    },
    "terms": [
      {
        "contractPeriod": "<string>",
        "cancellationPeriod": "<string>",
        "contractPeriodLabel": "<string>",
        "cancellationPeriodLabel": "<string>"
      }
    ],
    "contractStart": "<string>",
    "contractEnd": "<string>",
    "poNumber": "<string>"
  },
  "signers": [
    {
      "name": "<string>",
      "roleLabel": "<string>",
      "isCountersigner": true,
      "firstName": "<string>",
      "signingStatus": "<string>",
      "isMe": true
    }
  ],
  "recipient": {
    "id": "<string>",
    "firstName": "<string>",
    "lastName": "<string>",
    "email": "<string>",
    "role": "<string>",
    "signingUrl": "<string>",
    "termsAccepted": true
  },
  "recipients": [
    {
      "id": "<string>",
      "firstName": "<string>",
      "lastName": "<string>",
      "role": "<string>",
      "isMe": true
    }
  ],
  "billingData": {
    "state": "<string>",
    "providedByFirstName": "<string>",
    "costCenter": "<string>",
    "leitwegId": "<string>"
  },
  "resolvedVariables": {},
  "documentUrl": "<string>",
  "signedDocumentUrl": "<string>",
  "billingRecipient": {
    "company": "<string>",
    "contactName": "<string>",
    "addressLines": [
      "<string>"
    ],
    "billingEmail": "<string>",
    "vatId": "<string>"
  },
  "buyer": {
    "companyName": "<string>",
    "salutation": "<string>",
    "firstName": "<string>",
    "lastName": "<string>",
    "street": "<string>",
    "houseNumber": "<string>",
    "zip": "<string>",
    "city": "<string>",
    "country": "<string>",
    "vatId": "<string>",
    "addition": "<string>",
    "addressId": "<string>"
  },
  "billing": {
    "companyName": "<string>",
    "salutation": "<string>",
    "firstName": "<string>",
    "lastName": "<string>",
    "street": "<string>",
    "houseNumber": "<string>",
    "zip": "<string>",
    "city": "<string>",
    "country": "<string>",
    "vatId": "<string>",
    "addition": "<string>",
    "addressId": "<string>"
  },
  "billingEmail": "<string>",
  "poNumber": "<string>",
  "tenantSettings": {
    "allowReject": true,
    "printFallbackAlways": true
  },
  "termsUrl": "<string>",
  "privacyUrl": "<string>",
  "logoUrl": "<string>",
  "contactPerson": {
    "id": "<string>",
    "firstName": "<string>",
    "lastName": "<string>",
    "email": "<string>",
    "avatar": "<string>",
    "phone": "<string>",
    "linkedin": "<string>",
    "position": "<string>",
    "website": "<string>"
  },
  "sections": [
    "<string>"
  ],
  "showDsrRoom": true,
  "offerLineItems": [
    "<string>"
  ],
  "signed": true,
  "canSign": true
}

Pfadparameter

id
string
erforderlich

Offer identifier

Antwort

Offer resource

name
string
id
string

Stabiler ULID des Angebots ((string) Offer::getId()). Zusammen mit recipientId bildet es das Composite-Credential {id}-{recipientId}, mit dem die käuferseitigen POST-Endpoints (click-accept, signature-session, terms-acceptance, invoice-details, signed-upload, po-upload, delegate) adressiert werden. Ohne dieses Feld baute offer-view die Adresse als undefined-{recipientId} und der Server verwarf sie mit „Invalid ULID" (FYNN-3272). Auch auf dem Dokument-Level-/Preview-Pfad gesetzt — nur recipientId ist dort null.

number
string

Menschenlesbare Angebotsnummer (Offer::getNumber()) — treibt das Eyebrow „Angebot ANG-…“ im Buyer-Header.

recipientId
string | null

Credential des anfragenden Empfängers ((string) OfferRecipient::getId()).

startDate
string | null

FYNN-3264 — Vertragsbeginn (ISO) für die Detail-Box der Rail (Start-Zeile).

signedAt
string<date-time> | null

D11 — Zeitpunkt der Signatur/Annahme (Offer::getSignedAt()); serialisiert ISO-8601. Treibt die „Angenommen am …“-Anzeige der Success-Rail. Null, solange keine Signatur erfasst wurde.

Beispiel:

"2021-01-01T00:00:00+00:00"

acceptanceMode
string
Standard:click

D9 — offer-level acceptance mode (click | esignature | print).

Beispiel:

"click"

status
string
Standard:open

Offer state machine current step (open | signing | awaiting_invoice_details | signed | archived).

Beispiel:

"open"

isPreview
boolean

D20 — true nur auf dem Live-Preview-Pfad (GET /public/offers/{offerId}/preview): gerendert wird der DRAFT-Stand ohne Recipient-Kontext; offer-view zeigt das Preview-Banner.

validUntil
string<date-time> | null

D7 — offer-expiry timestamp (null if not set); serialises ISO-8601.

Beispiel:

"2021-01-01T00:00:00+00:00"

dealType
string
Standard:new_business

D2 — denormalised deal type (new_business | expansion | renewal | one_off).

Beispiel:

"new_business"

contractValue
object

D6 — read-time recurring contract value, honouring flat_fee invariant.

termLabel
string | null

D3 — read-time derived contract-term label, du-Form.

proposal
object

Berechnetes Proposal-View-Model: Phasen, Posten, Rabatte, Summen (Euro).

signers
object[]

Dokument-Level Unterzeichner — treibt die Signatur-Zeilen bzw.

recipient
object

D13 — der anfragende Empfänger selbst: persönliche signingUrl (Docuseal-Session) und Terms-Gate-Zustand. Null auf dem Dokument-Level-/Preview-Pfad ohne Recipient-Credential.

recipients
object[]

D13 — Auswahl-Kandidaten für den Zeremonie-Dialog (ohne E-Mail-Adressen Dritter, ohne Countersigner); isMe markiert den aktuellen Empfänger.

billingData
object

D12 — Zustand der Rechnungsdaten (Parallel-Track): missing | incomplete | complete plus Vorname der erfassenden Person für die first-writer-wins-Anzeige.

resolvedVariables
object

Aufgeloeste Platzhalter (name => Wert) fuer den variable-Block. Daten berechnet das Backend (Datumsformate fertig); die Frontends ersetzen nur.

documentUrl
string | null

D15 — absolute URL des bestehenden öffentlichen Document-Endpoints (GET /public/offers/{offerId}-{recipientId}/document, API-Domain der Organisation) für genau dieses Credential; treibt den „PDF herunterladen“-Pfad der Print-Annahme. Ohne Recipient (Preview/ Dokument-Level) wird das Versions-Credential sha1(offerId + number) verwendet. Null, wenn der Organisation keine API-Domain zugeordnet ist.

signedDocumentUrl
string | null

B1 FYNN-3243 — absolute URL des versiegelten, vollständig unterschriebenen Angebots-PDFs (inkl. Abschlusszertifikat). Mappt auf {@see \Fynn\Core\Domain\Offer\Model\Offer::getSignedDocument()} (Media) und ist nur gesetzt, sobald ALLE Unterzeichner unterschrieben haben — also ab Status awaiting_invoice_details (signed/archived eingeschlossen).

billingRecipient
object

FYNN-3264 — Rechnungsempfänger-Sektion der Success-Rail. ≠ null ⇒ vorhandene Zusammenfassung + „Anpassen“; null ⇒ CTA „vervollständigen“.

buyer
object

FYNN-3299 — strukturierte Käuferadresse (Kunde) aus dem parties-Block, autoritativ vom Backend. Quelle für das Vorbefüllen des Rechnungsdaten- Formulars (Fallback, wenn „Rechnung an" leer/„Wie Kunde" ist). Null, wenn der Verkäufer keinen Käufer gepflegt hat.

billing
object

FYNN-3299 — strukturierte Rechnungsadresse (Rechnung an) aus dem parties-Block. Das Rechnungsdaten-Formular (InvoiceDetailsForm) wird IMMER hieraus vorbefüllt; ist „Rechnung an" leer/„Wie Kunde", fällt es auf {@see self::$buyer} zurück. Trägt addressId ≠ null, wenn der Verkäufer eine unveränderte Bestandsadresse gewählt hat — dann bietet das offer-view sie zum Bestätigen an, statt das leere Formular zu zeigen.

billingEmail
string | null

FYNN-3299 — abgeleitete Rechnungs-E-Mail aus dem parties-Block (Kontakt der Rechnungspartei, sonst des Käufers) zum Vorbefüllen des Formulars.

poNumber
string | null

FYNN-3299 — vorbelegte PO-/Bestellnummer aus dem parties-Block (attrs.poNumber).

tenantSettings
object

FYNN-3264 — Organisations-Schalter für die Off-Ramps der Buyer-Shell (allowReject, printFallbackAlways). Sichere Defaults (beide false).

termsUrl
string | null

D13/D22 — Link-Ziele der Terms-Checkbox am Signatur-CTA, aus der Tenant-Appearance (conditionsUrl → termsUrl, privacyUrl). Null, wenn die Organisation keine URL gepflegt hat — das Frontend rendert den Begriff dann als reinen Text statt als Link.

privacyUrl
string | null
logoUrl
string

FYNN-3294 — autoritatives Brand-Logo der Organisation für genau dieses Angebot (gespeichertes Appearance-Logo des Offer-Vertriebskanals, Fallback Default-Channel). Anders als der host-aufgelöste /public/sales-channel/config trägt das Angebot seinen Tenant immer mit sich — der öffentliche offer-view-Link hat keinen Tenant-Host, weshalb die Config dort das Logo nicht zuverlässig auflösen kann. offer-view bevorzugt darum dieses Feld für Header UND Druck/PDF. NIE leer: ohne gepflegtes Logo greift der App-Logo-Fallback ({@see \Fynn\Core\Domain\Tenant\Model\Appearance::getLogoUrl()} mit Fallback), damit das Logo „IMMER" erscheint.

contactPerson
object
sections
string[]
showDsrRoom
boolean

FYNN-3421 — autoritative Entscheidung, ob die käuferseitige Ansicht den Digital-Sales-Room-Rahmen rendert oder das Angebot direkt zum Signieren zeigt. true nur, wenn das Angebot tatsächlich DSR-Inhalt trägt (mindestens eine versteckte/„Nur DSR“-Section mit Inhalt). Ohne DSR-Blöcke false — die Frontends fallen dann auf die direkte, signierbare Angebots-Ansicht zurück statt eine leere Raum-Hülle zu zeigen. Die Frontends rendern nur dieses Flag, sie leiten es nicht selbst ab.

offerLineItems
string[]
signed
boolean
canSign
boolean