gigafibre-fsm/docs/giftbit-integration-overview.md
louispaulb 00f2e735c8 docs: Giftbit API integration overview for production approval
Reviewer-facing document covering company/use-case, why we need
delivery_type=SHORTLINK (brand+language+deliverability), what data
we send (no PII beyond name/email/internal opaque ID), security
posture (token in env, sandbox-by-default with email override
to a single test inbox), CASL compliance, customer experience,
and the planned /gifts/{uuid} redemption polling.

Provided as a single markdown file under docs/ so it can be exported
to PDF for the Giftbit review team.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 09:26:05 -04:00

13 KiB
Raw Permalink Blame History

Giftbit API Integration — TARGO Communications

Prepared for: Giftbit Integration Review Team Submitted by: TARGO Communications (operating as Gigafibre) Company website: https://www.targo.ca Primary technical contact: Louis Paul — louis@targo.ca Last updated: 2026-05-22


1 · Company and Use Case

TARGO Communications is a Quebec-based fibre-optic Internet Service Provider headquartered in Sainte-Clotilde-de-Châteauguay (Montérégie region). We operate under the consumer-facing brand Gigafibre and serve residential and commercial customers across several municipalities in southwestern Quebec.

Our intended use of the Giftbit API is a customer retention and loyalty program. We send gift-card emails to existing TARGO customers as a thank-you and a soft incentive to maintain their service term. Recipients are exclusively current customers in our billing system (ERPNext); we never send to leads, prospects, or purchased lists. All recipients have an active service agreement that includes consent to receive transactional and relationship-related communications from TARGO (Canada CASL implied consent for current business relationships).

Typical campaign profile:

Parameter Value
Volume per campaign 150 300 recipients
Frequency 1 2 campaigns per year, per region
Face value per gift CAD 50 60
Brand mix Canadian retailers — Tim Hortons, Walmart Canada, Home Depot Canada, IGA, Home Hardware (Amazon was intentionally removed from our brand selection to reinforce the "buy local" messaging in our copy)
Recipient profile Existing residential fibre customers in Quebec

2 · Why We Need the API (vs. Giftbit's Standard Email Delivery)

We selected delivery_type=SHORTLINK for three reasons that we believe align with Giftbit's intent:

  1. Brand and language consistency. Our customer base is primarily French-speaking. The email a TARGO customer receives needs to be in French, match our visual brand (Plus Jakarta Sans typography, our green #00C853, our footer with mailing address and support contact), and read in our informal Quebec voice (tutoyer). Giftbit's default English templates would feel jarring and erode the trust we have with our customers.

  2. Deliverability ownership. Our domain targo.ca has SPF/DKIM/DMARC alignment with Mailjet, our ESP. Sending all customer communications through our own validated infrastructure keeps our sender reputation consistent and avoids domain-spoofing risk that recipients might (legitimately) flag.

  3. Engagement attribution. We need to know whether our specific creative succeeded. The data we get from Mailjet's webhook (open, click on the gift CTA specifically, bounce) feeds our internal analytics and informs the next campaign's copy.

We do not use the API to bulk-create gifts that we then redistribute, resell, or use as marketing prospect bait — every gift is tied 1:1 to a named existing customer record in our ERP at the moment of campaign creation.


3 · Technical Implementation Overview

3.1 · Architecture

   ┌─────────────────────┐
   │ Our ops console     │   internal Vue/Quasar SPA at
   │ (CampaignNewPage)   │   https://erp.gigafibre.ca/ops
   └──────────┬──────────┘
              │ 1) operator triggers Giftbit campaign create
              ▼
   ┌─────────────────────┐   create_giftbit_campaign.js
   │ Node script (CLI)   │   • POST /papi/v1/campaign with
   │ create_giftbit…js   │     delivery_type=SHORTLINK
   └──────────┬──────────┘   • polls /papi/v1/gifts until shortlinks created
              │ 2) writes giftbit-gifts-<id>.csv to disk
              ▼
   ┌─────────────────────┐
   │ Our hub service     │   3) operator uploads the Giftbit CSV alongside
   │ (Node, Mailjet SMTP)│      a customer-contact CSV; the hub pairs them
   └──────────┬──────────┘      and sends one personalized FR/EN email
              │                 per recipient via Mailjet
              ▼
   ┌─────────────────────┐
   │ Customer's inbox    │
   └──────────┬──────────┘
              │ click on CTA → opens Giftbit shortlink
              ▼
   ┌─────────────────────┐
   │ Giftbit's branded   │   recipient chooses brand, redeems on
   │ redemption page     │   Giftbit-hosted UI (we never touch the code)
   └─────────────────────┘

3.2 · API Endpoints Used

All requests go to:

  • Production: https://api.giftbit.com/papi/v1
  • Sandbox: https://api-testbed.giftbit.com/papi/v1
Method Path Purpose
GET /ping Token sanity check at startup of every CLI run
POST /campaign Create a new gift campaign with delivery_type: "SHORTLINK"
GET /gifts?campaign_uuid=… Poll for generated shortlinks (Giftbit creates them asynchronously)
GET /gifts/{uuid} (Planned, see §6) Periodic redemption-status polling per gift

3.3 · POST /campaign payload (production-shape)

{
  "id": "targo-2026-q2-loyalty",
  "subject": "Cadeau TARGO — merci",
  "message": "Merci d'être client TARGO. Voici une carte-cadeau pour vous remercier.",
  "expiry": "2026-12-31",
  "price_in_cents": 6000,
  "brand_codes": ["timhortonsca", "walmartca", "homedepotca", "igacaca", "homehardwareca"],
  "contacts": [
    { "id": "ERPNEXT-CUST-001234", "firstname": "Marie", "lastname": "Tremblay", "email": "marie@example.com" },
    { "id": "ERPNEXT-CUST-001235", "firstname": "Jean",  "lastname": "Bouchard", "email": "jean@example.com" }
  ],
  "delivery_type": "SHORTLINK"
}

The id field on each contact carries our internal ERPNext Customer ID. This is what lets us reconcile redemption events back to a specific customer record without any PII (postal code, phone, address) ever crossing the API boundary.

3.4 · What we send / what we don't send

Field sent to Giftbit Sent? Notes
First name Used only for the shortlink landing page personalization
Last name Same
Email address Required by Giftbit's data model even with SHORTLINK; never used for outbound mail by Giftbit when SHORTLINK is set
Internal customer ID Opaque string, no PII embedded
Phone number Never
Postal address Never
Service plan / billing info Never
Demographics Never

4 · Security Posture

4.1 · Credential handling

  • Giftbit API token is stored only in the environment of our production hub container (GIFTBIT_TOKEN env var, loaded from a .env file with chmod 600). The token never appears in source code or in our Gitea repository.
  • All API calls are made over HTTPS using Node's native https module with default TLS validation. We do not disable certificate verification.

4.2 · Sandbox isolation

  • During all development and pre-flight QA we use api-testbed.giftbit.com exclusively (--sandbox CLI flag enforces this).
  • When the sandbox flag is set, every contact email in the CSV is overridden to a single internal test inbox (louis@targo.ca). This means even if a developer mistakenly uses real customer data while testing, no test gift can be sent to a real customer.
  • Production runs require explicit removal of the --sandbox flag and are gated by a manual operator confirmation step in our ops console.
  • Each shortlink is consumed at most once on Giftbit's side. We do not log shortlinks in any plain-text channel (no Slack, no email, no analytics dashboards).
  • The shortlink only travels through:
    1. Our hub's JSON campaign file on disk (filesystem perms 600, Docker volume not exposed to internet)
    2. The outbound Mailjet email to the named recipient
    3. The Mailjet click webhook event (where Mailjet provides the URL alongside CustomID = <campaign>:<row> so we can reconcile without re-exposing the link in logs)

4.4 · Webhook authenticity

  • We are aware that Mailjet click events carry the original URL. We use this only to distinguish gift-CTA clicks from other link clicks for our analytics; the shortlink itself is not echoed back to any external system from our webhook handler.

5 · Compliance and Customer Experience

  • 100% of recipients have an active service agreement with TARGO containing implied consent for relationship and transactional messages.
  • Every campaign email includes our physical mailing address and a working support@targo.ca contact, satisfying CASL section 6(2)(c) identification requirements.
  • We provide a one-click way to refuse or request a replacement gift by replying to support@targo.ca. Refused gifts are returned to our Giftbit balance (/gifts/{uuid} cancellation, planned in §6).

5.2 · Recipient experience

  1. Customer opens the email in their inbox. Sender is TARGO <noreply@targo.ca>, subject "🎁 Un cadeau pour toi, de la part de TARGO" (or English equivalent based on the customer's preferred language flag in ERPNext).
  2. Email displays the customer's first name, the gift face value (e.g. "60 $"), the brand selection (rendered as small inline logos), a single primary CTA button leading to the Giftbit shortlink, and a brief plain-language disclosure of any commitment terms.
  3. On click, the customer lands on Giftbit's hosted redemption page. They select a brand from the campaign's allowed list and follow Giftbit's standard redemption flow. We have no visibility into the redemption form itself.
  4. The customer's record in our system is annotated with gift_link_clicked = true and timestamp upon return webhook from Mailjet. Redemption confirmation will (per §6) be polled directly from /gifts/{uuid}.

5.3 · Data retention

  • Campaign JSON files (including shortlinks) are retained on the hub for 24 months for accounting and customer-support traceability, after which they are archived to encrypted cold storage and removed from the live system.
  • We do not share, sell, or otherwise distribute any data collected from this integration to third parties.

6 · Planned Next Steps — Redemption Status Polling

We intend to add a recurring background poll against GET /gifts/{uuid} for each issued shortlink in an active campaign window. The plan:

Cadence Action
T + 1 hour First poll for every gift after campaign send completes
T + 1 day, +7 d, +30 d Subsequent polls until either the gift is REDEEMED or expiry passes
On expiry + 1 day Final reconciliation poll, then move the recipient row to a "closed" state

The polled status (NEW / LINKCREATED / REDEEMED / REFUNDED) and the brand the recipient selected will be persisted on the same per-recipient JSON row alongside gift_link_clicked_at. This lets us produce a single CSV report covering the full lifecycle:

row, firstname, email, gift_url, gift_clicked_at,
gift_status (REDEEMED/etc), gift_redeemed_at, gift_brand_selected

We will respect Giftbit's published rate limits and apply exponential backoff on 429/5xx responses. Polling will be batched (single request returns up to 500 gifts via ?campaign_uuid=…&limit=500), so even a 1000-recipient campaign costs at most two requests per polling cycle.


7 · Source Code References (read-only access available on request)

File Purpose
scripts/campaigns/create_giftbit_campaign.js The POST /campaign + shortlink-polling CLI that talks to Giftbit
services/targo-hub/lib/campaigns.js Hub service: CSV pairing, Mailjet send, webhook receiver, planned /gifts/{uuid} poller
apps/ops/src/modules/campaigns/ Internal Vue/Quasar console where operators create and monitor campaigns
services/targo-hub/templates/gift-email-fr.html The French email template (HTML)
services/targo-hub/templates/gift-email-en.html The English email template

Repository (Giftbit reviewers can be added on request): https://git.targo.ca/louis/gigafibre-fsm


8 · Contacts

Role Name Email
Owner / Lead developer Louis Paul louis@targo.ca
Customer support (recipients use this) TARGO Support support@targo.ca
Mailing address TARGO Communications, 1867 ch. de la rivière, Sainte-Clotilde, QC, Canada

We are happy to walk through the code, demonstrate the ops console live, or send a small sample campaign through the sandbox if that would help your review. Please let us know what level of detail or evidence would be most useful.

Thank you for your time.

TARGO Communications · 2026