Push · Arazzo Workflow

Onboard a guest and send a welcome message

Version 1.0.0

Check the account has credit, create a guest contact in Cendyn CRM (PUSHTech) with GDPR consent recorded, subscribe them to an audience list, send a welcome email, and confirm the delivery reached a terminal status. Authored by API Evangelist against the derived OpenAPI; every operationId is verified to exist in that spec.

1 workflow 1 source API 1 provider
View Spec View on GitHub CompanyCRMCustomer Data PlatformMarketing AutomationHospitalityHotelsGuest ExperienceEmailSMSPush NotificationsWebhooksSegmentationArazzoWorkflows

Provider

push

Workflows

onboardAndWelcomeGuest
Create a guest contact, subscribe them to a list, send a welcome email and confirm delivery.
NOTE — this API publishes no idempotency contract. If step sendWelcomeEmail fails with a network error, do NOT re-run the workflow: run listDeliveries filtered by contact_id first to determine whether the message was already sent, or the guest receives it twice and the account is charged twice.
6 steps inputs: accountId, email, firstName, gdprDate, gdprMarketingConsent, gdprRemoteIp, language, lastName, userId, welcomeSubject outputs: balanceBefore, contactId
1
checkBalance
currentBalanceAccount
Confirm the account has credit before doing anything that spends it. Deliveries and email validation draw this balance down; there is no documented behaviour at zero.
2
findExistingContact
listContact
Look the guest up by your own user_id before creating them. There is no idempotency on createContact, so this check is the only thing standing between a retry and a duplicate guest record.
3
createContact
createContact
Create the guest with consent recorded in the same call. Returns 201 with the contact id — a 24-character hex string that is the handle for every downstream step.
4
listAudienceLists
listAudienceList
Find the audience list to subscribe the new guest to.
5
sendWelcomeEmail
sendEmailDeliveries
CONSEQUENTIAL STEP — this reaches a real person and spends real credit, and it is not idempotent. Gate it behind confirmation in any autonomous loop.
6
confirmDelivery
listDeliveries
Follow the message to a terminal status. Match on "deliverd" — the misspelling is in the provider's own published status vocabulary. "undefined" is also a real value in that enum.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Onboard a guest and send a welcome message
  version: 1.0.0
  description: >-
    Check the account has credit, create a guest contact in Cendyn CRM (PUSHTech) with GDPR
    consent recorded, subscribe them to an audience list, send a welcome email, and confirm the
    delivery reached a terminal status. Authored by API Evangelist against the derived OpenAPI;
    every operationId is verified to exist in that spec.
sourceDescriptions:
  - name: cendynCrm
    url: ../openapi/push-cendyn-crm-openapi.yml
    type: openapi
workflows:
  - workflowId: onboardAndWelcomeGuest
    summary: Create a guest contact, subscribe them to a list, send a welcome email and confirm delivery.
    description: >-
      NOTE — this API publishes no idempotency contract. If step sendWelcomeEmail fails with a
      network error, do NOT re-run the workflow: run listDeliveries filtered by contact_id first
      to determine whether the message was already sent, or the guest receives it twice and the
      account is charged twice.
    inputs:
      type: object
      required: [accountId, userId, email, firstName, lastName]
      properties:
        accountId:
          type: string
          description: The Cendyn CRM account id. Not derivable from the token — it must be supplied.
        userId:
          type: string
          description: Your own backend identifier for this guest. The documented de-duplication key.
        email:
          type: string
          description: Guest email. Either email or phone_countrycode plus phone_number is required.
        firstName: {type: string}
        lastName: {type: string}
        language:
          type: string
          description: ISO-2 language code, e.g. ES.
          default: EN
        gdprMarketingConsent: {type: boolean, default: false}
        gdprDate:
          type: string
          description: ISO 8601 timestamp of when consent was given.
        gdprRemoteIp:
          type: string
          description: The IP address the guest consented from.
        welcomeSubject: {type: string, default: Welcome}
    steps:
      - stepId: checkBalance
        description: >-
          Confirm the account has credit before doing anything that spends it. Deliveries and
          email validation draw this balance down; there is no documented behaviour at zero.
        operationId: currentBalanceAccount
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
        successCriteria:
          - condition: $statusCode == 200
        outputs:
          balance: $response.body#/balance
          currency: $response.body#/currency

      - stepId: findExistingContact
        description: >-
          Look the guest up by your own user_id before creating them. There is no idempotency on
          createContact, so this check is the only thing standing between a retry and a duplicate
          guest record.
        operationId: listContact
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
          - name: user_id
            in: query
            value: $inputs.userId
        successCriteria:
          - condition: $statusCode == 200

      - stepId: createContact
        description: >-
          Create the guest with consent recorded in the same call. Returns 201 with the contact
          id — a 24-character hex string that is the handle for every downstream step.
        operationId: createContact
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
        requestBody:
          contentType: application/json
          payload:
            user_id: $inputs.userId
            email: $inputs.email
            name_first: $inputs.firstName
            name_last: $inputs.lastName
            language: $inputs.language
            gdpr_marketing_consent: $inputs.gdprMarketingConsent
            gdpr_accept_terms: true
            gdpr_date: $inputs.gdprDate
            gdpr_remote_ip: $inputs.gdprRemoteIp
        successCriteria:
          - condition: $statusCode == 201
        outputs:
          contactId: $response.body#/id

      - stepId: listAudienceLists
        description: Find the audience list to subscribe the new guest to.
        operationId: listAudienceList
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
        successCriteria:
          - condition: $statusCode == 200

      - stepId: sendWelcomeEmail
        description: >-
          CONSEQUENTIAL STEP — this reaches a real person and spends real credit, and it is not
          idempotent. Gate it behind confirmation in any autonomous loop.
        operationId: sendEmailDeliveries
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
        requestBody:
          contentType: application/json
          payload:
            contact_id: $steps.createContact.outputs.contactId
            subject: $inputs.welcomeSubject
        successCriteria:
          - condition: $statusCode == 200

      - stepId: confirmDelivery
        description: >-
          Follow the message to a terminal status. Match on "deliverd" — the misspelling is in the
          provider's own published status vocabulary. "undefined" is also a real value in that
          enum.
        operationId: listDeliveries
        parameters:
          - name: account_id
            in: path
            value: $inputs.accountId
          - name: contact_id
            in: query
            value: $steps.createContact.outputs.contactId
        successCriteria:
          - condition: $statusCode == 200
    outputs:
      contactId: $steps.createContact.outputs.contactId
      balanceBefore: $steps.checkBalance.outputs.balance