OpenAPI 3.0 · REST · JSON

Lead Posting API

Send consumer leads into the Pennie distribution network. The engine evaluates each lead in real time and returns matched offers from active bidding partners.

Version
1.0.0
Auth
OAuth 2.0 CC
Format
application/json
Token TTL
3600s

Base URL

Base URLs are partner-specific and provided directly by Pennie during onboarding. All endpoint paths in this document are relative to your assigned base URL.

Format  —  Your base URL follows the pattern below. The subdomain is unique to your integration and will be confirmed by your Pennie account manager.
URL format
https://<partner>.trypennie.dev

Full Endpoint URLs

Constructed from your assigned base URL
Authentication
https://<partner>.trypennie.dev/token
Lead Posting
https://<partner>.trypennie.dev/bidding

Authentication

This API uses the OAuth 2.0 Client Credentials flow. Credentials are partner-specific and issued by Pennie at onboarding.

Best practice: Cache your token and reuse it until close to expiry. Requesting a new token on every lead post adds unnecessary latency.

POST /token

Exchange client credentials for a Bearer access token.

POST /token Request Access Token

Pass your credentials as an HTTP Basic Authorization header. The grant_type query parameter must be set to client_credentials.

Full URL:  https://<partner>.trypennie.dev/token

Headers

Authorizationrequired
string
Basic <Base64(client_id:client_secret)>

Query Parameters

grant_typerequired
string
Must be client_credentials

Example Request

cURL
curl -X POST "https://<partner>.trypennie.dev/token?grant_type=client_credentials" \
  -H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)"

Response — 200 OK

JSON
{
  "access_token": "at_0ef932a01d9303d4c7fc07b8a650...",
  "expires_at":   1753214916,
  "expires":      3600,
  "token_type":   "Bearer"
}
Response Fields
access_token
string
Bearer token for use in subsequent requests.
expires_at
integer
Unix timestamp (UTC) when this token expires.
expires
integer
Seconds until expiry from time of issue. Always 3600.
token_type
string
Always Bearer.

POST /bidding

Submit a consumer lead into the Pennie distribution network and receive matched offers in real time.

POST /bidding Submit Lead for Bidding

Requires a valid Bearer token in the Authorization header obtained from /token.

Full URL:  https://<partner>.trypennie.dev/bidding
Tracking IDs: The exact field names and expected values for leadId1leadId4 are partner-specific. Pennie will confirm your required identifiers during onboarding.

Headers

Authorizationrequired
string
Bearer <access_token>
Content-Typerequired
string
application/json

Tracking Identifiers PARTNER-SPECIFIC

Campaign Tracking IDs — confirmed per partner at onboarding
leadId1requiredpartner
string
Lead ID — Unique identifier for this lead record, generated by the posting partner.
leadId2requiredpartner
string
Publisher ID — Identifier for the publisher responsible for this lead.
leadId3requiredpartner
string
Campaign ID — Traffic or campaign source identifier. Use case defined per partner by Pennie.
leadId4optionalpartner
string
Custom Identifier 4 — Additional tracking field. Use case defined per partner by Pennie.

personalInformation required

firstNamerequired
string
Consumer's first name.
lastNamerequired
string
Consumer's last name.
emailrequired
string
Valid email address.
primaryPhonerequired
string
10-digit US phone number, digits only. Pattern: ^\d{10}$
address1required
string
Street address line 1.
address2optional
string
Apartment, suite, unit, etc.
cityrequired
string
City of residence.
staterequired
string
Two-letter US state abbreviation. Examples: PA CA TX
zipcoderequired
string
5-digit US ZIP code. Pattern: ^\d{5}$
dateOfBirthrequired
string
Format: YYYY-MM-DD  Example: 1985-07-22
ssnrequired
string
Full 9-digit SSN, digits only. Pattern: ^\d{9}$

loanInformation required

purposerequired
enum
Intended use of the requested loan.
30 accepted values
autoauto_purchaseauto_refinancebabyboatbusinesscar_repaircosmeticcredit_card_refidebt_consolidationemergencyengagementgreenhome_improvementhome_purchasehome_refihousehold_expenseslarge_purchaseslife_eventmedical_dentalmotorcyclemoving_relocationotherrvspecial_occasionstudent_loanstudent_loan_refitaxesunknownvacationwedding
loanAmountrequired
number
Requested loan amount in USD. Minimum: 1000

mortgageInformation required

propertyStatusrequired
enum
Consumer's current housing/property ownership status.
3 accepted values
own_outrightown_with_mortgagerent

creditInformation required

providedCreditRatingrequired
enum
Self-reported credit rating provided by the consumer.
6 accepted values
excellentgoodfairpoorlimitedunknown

financialInformation required

employmentStatusrequired
enum
Consumer's current employment status.
8 accepted values
employedemployed_full_timeemployed_part_timemilitarynot_employedself_employedretiredother
employmentPayFrequencyrequired
enum
How often the consumer is paid.
4 accepted values
weeklybiweeklytwice_monthlymonthly
annualIncomerequired
number
Annual income in USD.

educationInformation optional

educationLeveloptional
enum
Highest level of education attained by the consumer.
10 accepted values
high_schoolassociatebachelorsmastersdoctorateother_grad_degreecertificatedid_not_graduatestill_enrolledother

legalInformation required

consentsToFcrarequired
boolean
Consumer has provided FCRA authorization for a credit pull. Must be true.
consentsToTcparequired
boolean
Consumer has provided TCPA consent for contact. Must be true.

sessionInformation required

ipAddressrequired
string
Consumer's IP address at the time of form submission. Format: IPv4.
userAgentrequired
string
Browser User-Agent string from the consumer's session.

Example Request Body

JSON
{
  "leadId1": "lead_550e8400e29b41d4a716",
  "leadId2": "pub_abc123",
  "leadId3": "sub_source_xyz",
  "leadId4": "creative_001",
  "personalInformation": {
    "firstName":    "Jane",
    "lastName":     "Smith",
    "email":        "jane@example.com",
    "city":         "Philadelphia",
    "state":        "PA",
    "primaryPhone": "2155550123",
    "address1":     "123 Main Street",
    "address2":     "Apt 4B",
    "zipcode":      "19103",
    "dateOfBirth":  "1985-07-22",
    "ssn":          "123456789"
  },
  "loanInformation": {
    "purpose":    "debt_consolidation",
    "loanAmount": 15000
  },
  "mortgageInformation": {
    "propertyStatus": "rent"
  },
  "creditInformation": {
    "providedCreditRating": "good"
  },
  "financialInformation": {
    "employmentStatus":      "employed_full_time",
    "employmentPayFrequency": "biweekly",
    "annualIncome":          65000
  },
  "educationInformation": {
    "educationLevel": "bachelors"
  },
  "legalInformation": {
    "consentsToFcra": true,
    "consentsToTcpa": true
  },
  "sessionInformation": {
    "ipAddress": "192.168.1.100",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
  }
}

Responses

200 Accepted
200 Rejected
401 Unauthorized
500 Error

Lead accepted. Returns a list of matched offers. An empty offers array means no bids matched.

JSON
{
  "requestId": "req_abc123xyz",
  "offers": [
    {
      "name":         "partner_lender_a",
      "display_name": "Lender A",
      "rate":         12.5,
      "click_url":    "https://example-lender.com/apply?ref=pennie",
      "product_type": "personal_loan",
      "logo_src":     "https://cdn.trypennie.com/logos/lender_a.png",
      "offer_title":  "Personal Loan up to $20,000",
      "offer_details":"Fixed rate. No prepayment penalty."
    }
  ]
}

Lead failed validation or eligibility rules. Returned as HTTP 200 with a rejected status. The reason field contains a machine-readable rejection code.

JSON
{
  "lead_id": "30F7wmobcOeKg9Xe4h13k19rDr8",
  "status":  "rejected",
  "reason":  "invalid_state"
}

Missing or invalid Bearer token. Request a new token via /token and retry.

JSON
{
  "status": "error",
  "reason": "unauthorized"
}

Internal server error. Retry with exponential backoff. Contact Pennie support if the issue persists.

JSON
{
  "lead_id": "30F7wmobcOeKg9Xe4h13k19rDr8",
  "status":  "error",
  "reason":  "internal server error"
}

Tracking Identifiers

The four tracking identifier fields (leadId1leadId4) map to campaign-specific values confirmed by Pennie at onboarding.

Tracking ID Mapping
leadId1required
string
Lead ID — Your internal unique identifier for this lead record.
leadId2required
string
Publisher ID — Identifier for the publisher responsible for this lead.
leadId3required
string
Campaign ID — Traffic or campaign source identifier.
leadId4optional
string
Custom — Use case defined per partner (e.g. creative variant, funnel step).

Enum Reference

All accepted values for enumerated fields.

loanInformation.purpose
30 values
autoauto_purchaseauto_refinancebabyboatbusinesscar_repaircosmeticcredit_card_refidebt_consolidationemergencyengagementgreenhome_improvementhome_purchasehome_refihousehold_expenseslarge_purchaseslife_eventmedical_dentalmotorcyclemoving_relocationotherrvspecial_occasionstudent_loanstudent_loan_refitaxesunknownvacationwedding
mortgageInformation.propertyStatus
3 values
own_outrightown_with_mortgagerent
creditInformation.providedCreditRating
6 values
excellentgoodfairpoorlimitedunknown
financialInformation.employmentStatus
8 values
employedemployed_full_timeemployed_part_timemilitarynot_employedself_employedretiredother
financialInformation.employmentPayFrequency
4 values
weeklybiweeklytwice_monthlymonthly
educationInformation.educationLevel
10 values  ·  optional field
high_schoolassociatebachelorsmastersdoctorateother_grad_degreecertificatedid_not_graduatestill_enrolledother

Response Codes

HTTP Status Codes
200 OK
Lead accepted. Offers returned (may be empty if no bids matched).
200 Rejected
Lead rejected due to validation failure or eligibility rules. HTTP 200 with status: "rejected" and a machine-readable reason code.
401 Unauthorized
Missing or invalid Bearer token. Re-authenticate via /token.
500 Server Error
Internal error. Retry with exponential backoff. Contact support if persistent.
Pennie Partner Docs — Lead Posting API v1.0.0

Try It

Test the API against a sandbox endpoint using the dummy credentials below. No real data is submitted.

Sandbox base URL:  https://test-api.trypennie.dev
Test credentials — use these on the /token call:
client_id: test_client_pennie    client_secret: test_secret_pennie

Step 1 — Get a Token

POST /token Authenticate

Step 2 — Submit a Lead

POST /bidding Submit Lead
Tracking Identifiers
Personal Information
Loan Information
Mortgage Information
Credit Information
Financial Information
Education Information
Legal Information
Session Information
Request Preview
JSON
{}