Referral code, rules and results
const url = 'https://api.harperharbor.com/open/v1/me/referral';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.harperharbor.com/open/v1/me/referral \ --header 'Authorization: Bearer <token>'Returns the caller’s own referral code, the current reward rules and how many people the caller has referred. The code is created on first request and never changes. Results include aggregate counts and credits plus anonymous per-binding progress in invites (newest first, at most 50) and invitesTotal. They never identify the friends referred. pendingUntil is always present on each invite and may be null, including for a positive amount awaiting review. canRedeem tells whether the caller may still enter someone else’s code, and redeemUntil until when. Show terms to users instead of hard-coding reward numbers: the values can change. Requires the referral scope.
Authorizations
Section titled “Authorizations”Responses
Section titled “Responses”Referral page.
object
Whether codes can be entered and rewards are paid. When false the code and rules can still be shown.
The caller’s own referral code.
Current reward rules. All rewards are credits usable for agent conversations only. If a rewarded top-up is refunded, the unused part of its reward is withdrawn.
object
Credits a new user receives when entering a code. Each sign-in identity receives them once, and disposable email addresses receive none.
How many days the welcome credits stay valid; 0 means permanent (the current newcomer welcome gift).
Percentage of the referred user’s first top-up credited to the referrer once the payment has succeeded and the referral is bound. A top-up made before binding still counts as the first.
Maximum credits the referrer receives for one first top-up.
Extra percentage the referred user receives on their own first top-up, including one made before binding. 0 when not offered.
Percentage of each later top-up by the referred user credited to the referrer as soon as the payment succeeds.
How many days after binding the referred user’s top-ups keep earning the referrer rewards.
How many days after sign-up a new account can still enter a code.
Platform-funded credits for the original referrer of each eligible new-user binding during the inviter promotion; 0 outside the promotion. Independent of the ongoing newcomer welcome gift and the application campaign pool. Valid for inviterDays days (0 means permanent); replaying or switching the binding does not issue another gift.
Inclusive start of the inviter promotion, when configured.
Exclusive end of the inviter promotion, when configured.
Validity in days of the separate inviter promotion credit, measured from its issuance; independent of welcomeDays. 0 means permanent credits with no expiry.
Credits the original referrer receives when the referred friend completes their first successful, charged conversation within firstChatDays of binding. 0 outside the inviter promotion or when this reward is disabled. Eligibility uses the binding time within inviterStartAt (inclusive) and inviterEndAt (exclusive).
Days after binding in which the friend must complete their first successful, charged conversation. Returned even when firstChatCredits is 0. Eligible transition bindings use the new-rules launch plus this window; use each invite firstChatBy rather than calculating a deadline.
Whether the caller has entered someone’s code.
Welcome credits the caller received when entering a code; 0 when none.
Whether the caller can still enter a code. Also true while a binding made from a share link can still be replaced.
Last moment the caller can enter a code. Present only when canRedeem is true.
When the caller’s account was created. Compare it with the time the user opened a share link to tell whether the account was created after that visit.
How many accounts entered the caller’s code.
How many of them have topped up.
All referral credits already posted to the caller: binding rewards, first-conversation rewards, transition adjustments and top-up commissions. Pending credits are excluded.
Total referral credits whose conditions have been met but which are still awaiting settlement or review; 0 when none.
Next expected settlement time, when available. Omitted when no date is known; it does not include an invented date for rewards under review.
Bindings to the caller code, newest boundAt first, at most 50. Always present, including [] when empty. No friend identifiers or personal details are returned.
One anonymous friend binding. Contains progress and reward amounts, never the friend identity.
object
When the friend bound the caller code; not necessarily their sign-up time.
Waiting: no qualifying first conversation yet and still within the window; done: qualifying first conversation completed; expired: the deadline passed without one.
Deadline for a qualifying first conversation. Normally boundAt plus firstChatDays; eligible transition bindings use the new-rules launch plus the window.
Credits already posted from this binding, including binding, first-conversation and transition adjustment rewards; excludes top-up commissions.
Credits from this binding awaiting settlement or review; 0 when none.
Expected settlement time, or null when no date is known or pending is 0. This key is always present; a positive pending amount may still have null while under review.
Total bindings to the caller code; may exceed the number returned in invites.
Example
{ "invites": [ { "firstChat": "waiting" } ]}unauthorized — missing or invalid bearer.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}forbidden — the token was not granted referral.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}referral_disabled — referral rewards are not available right now; temporarily_unavailable — retry later.
object
Error code (snake_case) or, for legacy handlers, a free-text/localized message.
Human-readable sentence. Present only on middleware errors and /me, /me/wallet.
Whether retrying may succeed. Present only on middleware errors, /me, /me/wallet and service/share routes.
Only on a first-turn context_capacity_exceeded: the smallest context tier that fits the whole card with room to talk. Save it as context in player settings and resend. Absent when no tier fits.
The token budget of required_context_tier for the selected model, for display.
Only on a first-turn context_capacity_exceeded: whether saving trimConstantLore=true lets the card play at the current tier. Absent on mid-conversation capacity errors.
Only on insufficient_credits: the credits this turn needs before it can start. Absent when the refusal came without an estimate.
Only on insufficient_credits: the credits the wallet could set aside for it.
Examplegenerated
{ "error": "example", "message": "example", "retryable": true, "required_context_tier": 1, "required_context_tokens": 1, "constant_lore_trim_fits": true, "credits_needed": 1, "credits_available": 1}