Giveaway City API documentation

Integrate with one copy pasted ai prompt

Copy this prompt into your AI coding assistant inside your project. It includes authentication, the full API contract, automatic updates and withdrawal.

You will need publisher credentials to connect your finished integration.

List once. Keep your audience on your site.

Giveaway City aggregates giveaways from independent publishers. Your API integration keeps your listing up to date and sends visitors to your entry page. You manage entries, payments, draws and prizes.

1. Get publisher credentials

Sign in and create your publishing API key. No manual approval or token exchange is needed.

Get your API key

Save the key when it is shown: only its hash is stored, so it cannot be retrieved later. Send it as Authorization: Bearer YOUR_API_KEY from your server.

You can rotate or revoke it in API Access. Rotation immediately disables the previous key. Your listings stay attached to your account, including after revocation and recreation.

Existing Portal.Service client-credentials tokens remain supported for service integrations with audience service.giveawaycity and scope giveawaycity:publish. Their listings use a separate namespace; switching to a user API key requires an explicit migration. service.connects does not issue these keys.

2. Publish a listing

Base URL: https://dev.portal.raum.au/giveawaycity. Include any deployment path prefix. Replace the placeholder host if this deployment has not configured its public URL.

POST /api/v1/giveaways creates or replaces your listing. Use your own stable giveaway ID. Repeating the request updates the same listing instead of creating a duplicate.

curl --request POST "$GIVEAWAY_CITY_BASE_URL/api/v1/giveaways" \
  --header "Authorization: Bearer $GIVEAWAY_CITY_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "sourceExternalId": "spring-giveaway-2027",
  "title": "Win a gaming gift card",
  "description": "Enter on our website. See the official page for entry requirements, eligibility and full terms.",
  "landingUrl": "https://example.com/giveaways/spring-2027",
  "provider": "Example Gaming",
  "image": "https://example.com/images/spring-giveaway.jpg",
  "endDate": "2027-04-30T20:00:00Z"
}'

All fields are strings. Requests are limited to 32 KB. Send a full listing on each update: omitted optional fields reset to their defaults.

FieldRequired?Format
sourceExternalIdRequiredYour stable giveaway ID. Up to 200 characters. Reuse it for every update.
titleRequiredPublic title, up to 160 characters.
descriptionRequiredUp to 4,000 characters. Include entry costs, eligibility and important conditions.
landingUrlRequiredAbsolute HTTP(S) URL of your entry page, up to 2,048 characters.
providerOptionalPublic organizer name, up to 120 characters. Defaults to Independent publisher.
imageOptionalPublic absolute HTTP(S) image URL, up to 2,048 characters.
platformOptionalPlatform identifier, up to 80 characters; e.g. steam, pc, or all (default).
worthOptionalDisplay value, up to 40 characters; e.g. $100 AUD. Defaults to N/A.
instructionsOptionalHow to enter, up to 4,000 characters. Defaults to a link-out instruction.
endDateOptionalUTC ISO timestamp including seconds and Z; e.g. 2027-04-30T20:00:00Z. Defaults to N/A.

Success: HTTP 200 with { "listing": { ...publicFields, "status": "published", "updatedAt": "..." } }. Publisher ownership comes from your token. Listings start unverified; publishers cannot award themselves a trust badge.

3. Keep listings current

Send POST after publishing or editing. Read back your record with GET. Withdraw it when it closes, is cancelled or is deleted in your system.

# Read your listing (including withdrawn listings)
curl "$GIVEAWAY_CITY_BASE_URL/api/v1/giveaways?sourceExternalId=spring-giveaway-2027" \
  --header "Authorization: Bearer $GIVEAWAY_CITY_API_KEY"

# Withdraw; safe to repeat
curl --request DELETE "$GIVEAWAY_CITY_BASE_URL/api/v1/giveaways?sourceExternalId=spring-giveaway-2027" \
  --header "Authorization: Bearer $GIVEAWAY_CITY_API_KEY"

URL-encode the ID in query strings. DELETE returns HTTP 200 with the ID and status: withdrawn, even if already absent. POST with the same ID republishes it. GET returns 404 if this publisher has no matching record.

Use a durable queue and process each giveaway in order using its latest state. Reconcile periodically to repair missed updates. Public feed caches across instances can take up to 10 minutes to refresh.

Errors & retries

Error shape: { "error": { "message": "What to fix" } }.

  • 400: fix the payload. 413: reduce it below 32 KB. 415: send application/json.
  • 401: check whether your API key was rotated or revoked; update your server configuration. For Portal tokens, renew the token once. 403: check the required scope.
  • 404 on GET: check the external ID and publisher client.
  • Network failures and 5xx: use bounded exponential retries with jitter. Respect 429 and Retry-After if your gateway returns them.

Existing integrations using /api/integrations/publish-giveaway keep their legacy payload format, with publisher ownership checks. Existing unowned records require operator ownership migration before updates; they return 409 until assigned. New integrations should use v1. Legacy listings are not automatically transferred to the new publisher namespace; arrange migration with the operator before backfilling them.

Browse giveaways