Skip to main content

Rewarded App Development Guide - How to use the Swaarm Rewarded API

End-to-end Rewarded API guide for integrating Swaarm as a Rewarded Management Platform

Updated this week

Overview

Swaarm provides the RewardedUser feature that enables rewards app developers to manage demand inventory, track user task completions, and handle reward distributions.

The API associated with the product provides comprehensive user management, offer delivery, and analytics capabilities for your rewards application.

The API can be queried using GraphQL.

What is GraphQL?

GraphQL is a query language and runtime for APIs that allows clients to request exactly the data they need. Unlike REST APIs with multiple endpoints, GraphQL uses a single endpoint where you send queries and mutations to fetch or modify data.

GraphQL Clients and Libraries

You can interact with GraphQL APIs using various clients:

  • JavaScript/TypeScript

    • Apollo Client

    • urql

  • Mobile

    • Apollo iOS (Swift)

    • Apollo Android (Kotlin/Java)

    • graphql-flutter (Flutter)

Using standardised clients is highly recommended as it will automatically generate the types and verify that your queries are correct.

Making Requests with GraphQL

If a library is not wanted, you can also do GraphQL requests via HTTP POST requests to a single endpoint with a JSON body containing:

{
"query": "query GetUser { rewardedUser { id email } }",
"variables": {}
}

Getting Started with Rewarded API

Authentication

  • Registration: No authentication is required for user registration.

  • All Other Requests: You must authenticate using the login mutation and include the access token in subsequent requests.

NOTE: The access token is valid for 24 hours, you should request a new one whenever you get a 401 Error, or ideally every few hours to avoid authentication errors.

Login Mutation

mutation Login {
login(input: {
username: "rewardeduser@swaarm.com",
password: "newSuperSecurePasswrd123$"
}) {
authChallenge
token {
accessToken
refreshToken
tokenType
expiresIn
}
}
}

Using Access Tokens

Include the access token in the Authorization header for all authenticated requests:

Authorization: Bearer YOUR_ACCESS_TOKEN

GraphQL Endpoint

All API interactions use a single GraphQL endpoint which is provided in your Swaarm dashboard.

Construct your queries and mutations according to the schema outlined below.

Core Concepts

Users

Users are the users of your rewards app. Each user has a profile with personal information, custom fields, and associated offers and rewards.

Offers

Offers represent tasks or actions that users can complete to earn rewards. They include tracking URLs, creative assets, and payout information.

Rewards

Rewards track completed offers and the points/currency earned by users.

Events

Events represent specific completion milestones within offers, each with their own payout structure.

Schema Reference

Pagination

All list queries use offset-based pagination:

input Pagination {
offset: Int # Starting position (0-based)
limit: Int # Maximum number of items to return
}

RewardedUser

The central entity representing a user in your rewards app.

type RewardedUser {
id: String!
email: String!
nickName: String!
firstName: String
lastName: String
customFields: [RewardedUserProfileCustomField!]
status: RewardedUserStatus!
offers(filter: RewardedOffersFilter, pagination: Pagination!): RewardedOfferConnection!
rewards(pagination: Pagination!): RewardedUserRewardConnection!
report(input: RewardedReportInput!): RewardedReport!
internalId: String
referralId: String
}

Fields:

  • id: Unique identifier for the user, generated by Swaarm

  • email: User's email address (required)

  • nickName: Display name for the user

  • firstName, lastName: Optional personal information

  • customFields: Array of custom profile data for storing additional user information (e.g., preferences, app-specific data)

  • status: Current user status (ACTIVE, PENDING, INACTIVE)

  • offers: Available offers for this user (filtered and paginated)

  • rewards: User's completed rewards (paginated)

  • report: Analytics data for the user's activity

  • internalId: User's id given by the app if one exists

  • referralId: Id of the user that referred this user

Creating and Updating Users

Create User

Use the RewardedUserInput to create new users:

input RewardedUserInput {
internalId: String
email: String!
firstName: String
lastName: String
nickname: String
password: String!
country: String
status: RewardedUserStatus!
customFields: [RewardedUserProfileCustomFieldInput!]
referralId: String
}

Update User

Use RewardedUserUpdateInput to update existing user information:

input RewardedUserUpdateInput {
id: String!
internalId: String
firstName: String
lastName: String
nickname: String
country: String
customFields: [RewardedUserProfileCustomFieldInput!]
referralId: String
}

Available Mutations:

# Create a new user (no authentication required)
createRewardedUser(input: RewardedUserInput!): RewardedUser!

# Update existing user (authentication required)
updateRewardedUser(input: RewardedUserUpdateInput!): RewardedUser!

Example - Creating a User:

mutation CreateUser($input: RewardedUserInput!) {
createRewardedUser(input: $input) {
id
email
nickName
status
customFields {
name
value
}
}
}

Example - Updating a User:

mutation UpdateUser($input: RewardedUserUpdateInput!) {
updateRewardedUser(input: $input) {
id
nickName
firstName
lastName
customFields {
name
value
}
}
}

Filtering Offers

Use RewardedOffersFilter to control which offers are returned:

input RewardedOffersFilter {
autoFilter: Boolean # Apply automatic filtering based on user profile
excludeCompleted: Boolean # Hide offers already completed by the user
country: String # Filter by target country
keyword: String # Search offers by keyword
os: String # Filter by operating system
}

RewardedOffer

Represents a task or action that users can complete for rewards.

type RewardedOffer {
id: String!
name: String!
trackingUrl: String! # URL for tracking user interactions
impressionUrl: String # URL fired when offer is displayed
description: String
appStoreId: String # App store identifier if applicable
previewUrl: String # URL for previewing the offer
status: OfferStatus!
eventTypes: [RewardedEventType!]! # Steps users need to complete with payout info
leadflow: Leadflow! # Payment model (CPI, CPM, CPC, CPA, CPL, CPS)
kpi: String # Key performance indicators
additionalInformation: String
tags: [String!]
creatives: [RewardedOfferCreativePack!]
}

Payment Models (Leadflow)

  • CPI: Cost Per Install

  • CPM: Cost Per Mille (impressions)

  • CPC: Cost Per Click

  • CPA: Cost Per Action

  • CPL: Cost Per Lead

  • CPS: Cost Per Sale

RewardedUserReward

Tracks completed offers and associated events.

type RewardedUserReward {
offer: RewardedOffer!
completed: [RewardedCompletedEvent!]!
}

type RewardedCompletedEvent {
event: RewardedEventType!
theyGetPoints: Float # Points awarded to user
theyGet: Float # Currency/value awarded to user
time: LocalDateTime! # When the event was completed
}

Analytics and Reporting

Generate detailed reports using the RewardedReport system:

input RewardedReportInput {
start: LocalDateTime!
end: LocalDateTime!
granularity: RewardedReportInputGranularity! # DAY, WEEK, MONTH, YEAR, ALL
dimensions: [RewardedReportDimension!]! # DATETIME, OFFER_ID
}

type RewardedReport {
start: LocalDateTime!
end: LocalDateTime!
granularity: RewardedReportInputGranularity!
rows: [RewardedReportRow!]!
}

type RewardedReportRow {
dimensions: [RewardedReportDimensionResult!]!
theyGet: Float! # Total currency earned
theyGetPoints: Float! # Total points earned
}

Available Queries and Mutations

Queries

Get Current User

Retrieve the currently authenticated user's information:

query GetCurrentUser {
rewardedUser {
id
email
nickName
firstName
lastName
status
customFields {
name
value
}
}
}

Sample Response:

{
"data": {
"rewardedUser": {
"id": "user_12345",
"email": "user@example.com",
"nickName": "GamerPro",
"firstName": "John",
"lastName": "Doe",
"status": "ACTIVE",
"customFields": [
{
"name": "preferred_category",
"value": "gaming"
},
{
"name": "user_level",
"value": "advanced"
}
]
}
}
}

Mutations

Authentication

mutation Login($input: LoginInput!) {
login(input: $input) {
authChallenge
token {
accessToken
refreshToken
tokenType
expiresIn
}
}
}

Variables:

{
"input": {
"username": "developer@swaarm.com",
"password": "newSuperSecurePasswrd123$"
}
}

Sample Response:

{
"data": {
"login": {
"authChallenge": null,
"token": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "def502004a8c2c4e1f4d5a6b7c8d9e0f1...",
"tokenType": "Bearer",
"expiresIn": 3600
}
}
}
}

User Management

Create User:

mutation CreateUser($input: RewardedUserInput!) {
createRewardedUser(input: $input) {
id
email
nickName
status
customFields {
name
value
}
}
}

Variables:

{
"input": {
"email": "user@example.com",
"password": "userPassword123!",
"nickname": "GamerPro",
"firstName": "John",
"lastName": "Doe",
"country": "US",
"status": "PENDING",
"customFields": [
{
"name": "preferred_category",
"value": "gaming"
},
{
"name": "user_level",
"value": "beginner"
}
],
"referralId": "REF123456"
}
}

Sample Response:

{
"data": {
"createRewardedUser": {
"id": "user_12345",
"email": "user@example.com",
"nickName": "GamerPro",
"status": "PENDING",
"customFields": [
{
"name": "preferred_category",
"value": "gaming"
},
{
"name": "user_level",
"value": "beginner"
}
]
}
}
}

Update User:

mutation UpdateUser($input: RewardedUserUpdateInput!) {
updateRewardedUser(input: $input) {
id
nickName
firstName
lastName
customFields {
name
value
}
}
}

Variables:

{
"input": {
"nickname": "ProGamer2024",
"firstName": "John",
"lastName": "Smith",
"country": "CA",
"customFields": [
{
"name": "preferred_category",
"value": "action"
},
{
"name": "user_level",
"value": "advanced"
},
{
"name": "last_active",
"value": "2024-07-10"
}
]
}
}

Sample Response:

{
"data": {
"updateRewardedUser": {
"id": "user_12345",
"nickName": "ProGamer2024",
"firstName": "John",
"lastName": "Smith",
"customFields": [
{
"name": "preferred_category",
"value": "action"
},
{
"name": "user_level",
"value": "advanced"
},
{
"name": "last_active",
"value": "2024-07-10"
}
]
}
}
}

Common Query Examples

Get Current User with Available Offers

Query:

query GetUserOffers {
rewardedUser {
id
nickName
offers(
filter: {
excludeCompleted: true,
autoFilter: true
},
pagination: {
offset: 0,
limit: 20
}
) {
totalCount
edges {
node {
id
name
description
trackingUrl
leadflow
eventTypes {
id
name
description
payout {
theyGet
theyGetPoints
}
creativeUrl
creativeThumbnail
}
creatives {
title
creatives {
url
type
}
}
}
}
}
}
}

Sample Response:

{
"data": {
"rewardedUser": {
"id": "user_12345",
"nickName": "GamerPro",
"offers": {
"totalCount": 45,
"edges": [
{
"node": {
"id": "offer_67890",
"name": "Download SuperGame App",
"description": "Download and play SuperGame for 5 minutes to earn 100 points",
"trackingUrl": "https://track.example.com/click?offer=67890&user=12345",
"leadflow": "CPI",
"eventTypes": [
{
"id": "event_001",
"name": "App Install",
"description": "Download and install the SuperGame app",
"payout": {
"theyGet": 0.50,
"theyGetPoints": 50.0
},
"creativeUrl": "https://cdn.example.com/install_step.jpg",
"creativeThumbnail": "https://cdn.example.com/install_step_thumb.jpg"
},
{
"id": "event_002",
"name": "First Launch",
"description": "Open the app and complete the initial setup",
"payout": {
"theyGet": 0.25,
"theyGetPoints": 25.0
},
"creativeUrl": "https://cdn.example.com/launch_step.jpg",
"creativeThumbnail": "https://cdn.example.com/launch_step_thumb.jpg"
},
{
"id": "event_003",
"name": "Play 5 Minutes",
"description": "Play the game for at least 5 minutes",
"payout": {
"theyGet": 0.25,
"theyGetPoints": 25.0
},
"creativeUrl": "https://cdn.example.com/play_step.jpg",
"creativeThumbnail": "https://cdn.example.com/play_step_thumb.jpg"
}
],
"creatives": [
{
"title": "Main Campaign",
"creatives": [
{
"url": "https://cdn.example.com/creative_banner.jpg",
"type": "IMAGE"
},
{
"url": "https://cdn.example.com/creative_video.mp4",
"type": "VIDEO"
}
]
}
]
}
},
{
"node": {
"id": "offer_67891",
"name": "Complete Survey",
"description": "Answer a 5-minute survey about your gaming preferences",
"trackingUrl": "https://track.example.com/click?offer=67891&user=12345",
"leadflow": "CPL",
"eventTypes": [
{
"id": "event_004",
"name": "Survey Completion",
"description": "Complete the full survey with all questions answered",
"payout": {
"theyGet": 1.00,
"theyGetPoints": 100.0
},
"creativeUrl": "https://cdn.example.com/survey_completion.jpg",
"creativeThumbnail": "https://cdn.example.com/survey_completion_thumb.jpg"
}
],
"creatives": [
{
"title": "Survey Campaign",
"creatives": [
{
"url": "https://cdn.example.com/survey_banner.jpg",
"type": "IMAGE"
}
]
}
]
}
}
]
}
}
}
}

Get Current User's Completed Rewards

Query:

query GetUserRewards {
rewardedUser {
rewards(pagination: {
offset: 0,
limit: 20
}) {
totalCount
edges {
node {
offer {
id
name
}
completed {
event {
name
description
}
theyGetPoints
theyGet
time
}
}
}
}
}
}

Sample Response:

{
"data": {
"rewardedUser": {
"rewards": {
"totalCount": 12,
"edges": [
{
"node": {
"offer": {
"id": "offer_67890",
"name": "Download SuperGame App"
},
"completed": [
{
"event": {
"name": "App Install",
"description": "User successfully installed the app"
},
"theyGetPoints": 50.0,
"theyGet": 0.50,
"time": "2024-07-08T14:30:00"
},
{
"event": {
"name": "First Launch",
"description": "User opened the app for the first time"
},
"theyGetPoints": 25.0,
"theyGet": 0.25,
"time": "2024-07-08T14:32:15"
}
]
}
},
{
"node": {
"offer": {
"id": "offer_67891",
"name": "Complete Survey"
},
"completed": [
{
"event": {
"name": "Survey Completion",
"description": "User completed the full survey"
},
"theyGetPoints": 100.0,
"theyGet": 1.00,
"time": "2024-07-09T10:15:30"
}
]
}
}
]
}
}
}
}

Generate Current User Performance Report

Query:

query GetUserReport {
rewardedUser {
report(input: {
start: "2024-01-01T00:00:00",
end: "2024-12-31T23:59:59",
granularity: MONTH,
dimensions: [DATETIME, OFFER_ID]
}) {
rows {
dimensions {
dimension
value
}
theyGet
theyGetPoints
}
}
}
}

Sample Response:

{
"data": {
"rewardedUser": {
"report": {
"rows": [
{
"dimensions": [
{
"dimension": "DATETIME",
"value": "2024-06-01T00:00:00"
},
{
"dimension": "OFFER_ID",
"value": "offer_67890"
}
],
"theyGet": 2.50,
"theyGetPoints": 250.0
},
{
"dimensions": [
{
"dimension": "DATETIME",
"value": "2024-06-01T00:00:00"
},
{
"dimension": "OFFER_ID",
"value": "offer_67891"
}
],
"theyGet": 1.00,
"theyGetPoints": 100.0
},
{
"dimensions": [
{
"dimension": "DATETIME",
"value": "2024-07-01T00:00:00"
},
{
"dimension": "OFFER_ID",
"value": "offer_67890"
}
],
"theyGet": 1.75,
"theyGetPoints": 175.0
}
]
}
}
}
}

Integration Best Practices

Pagination

Always use pagination for list queries to manage performance:

pagination: {
offset: 0,
limit: 20
}

Offer Filtering

Use appropriate filters to show relevant offers:

  • Set excludeCompleted: true to hide already completed offers

  • Use autoFilter: true to apply platform-based filtering

  • Alternatively if autoFilter is not used you can filter by country and os for targeted offers

Tracking Implementation

  • Fire the `impressionUrl` when displaying offers to users

  • Use the `trackingUrl` to direct users to the offer

  • Monitor completion events to update reward balances

Error Handling

Implement proper error handling for network issues and GraphQL errors:

try {
const result = await graphqlClient.query({
query: GET_CURRENT_USER_OFFERS,
variables: {},
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
return result.data;
} catch (error) {
console.error('API Error:', error.graphQLErrors);
// Handle error appropriately
}

Custom Fields

Utilize custom fields to store additional user information that your app needs:

customFields: [
{ name: "preferred_category", value: "gaming" },
{ name: "user_level", value: "premium" },
{ name: "last_login_device", value: "ios" }
]

NOTE: Custom fields allow you to store any extra information about users that you want to display or use within your app, such as preferences, app-specific metadata, or user behavior data.

Status Management

User Status

  • ACTIVE: User can receive and complete offers

  • PENDING: User registration is complete but requires manual approval in the backend

  • INACTIVE: User is disabled

Offer Status

  • ACTIVE: Offer is available for completion

  • INACTIVE: Offer is no longer available

Creative Assets

Offers include creative packs with various media assets:

  • Images, videos, and other promotional materials

  • Multiple creative options for A/B testing

  • Thumbnail URLs for quick loading

Rate Limiting and Performance

  • Use pagination to limit response sizes

  • Consider implementing local caching for frequently accessed user data

Support and Troubleshooting

When integrating the API:

  1. Verify tracking URLs are firing correctly

  2. Ensure reward calculations match expected values

  3. Monitor completion events for accuracy

  4. Implement logging for debugging purposes

During implementation, please ask you Swaarm account manager to create a communication channel with one of Swaarm's integration engineers. They will help you with any technical questions.

During development, we can implement certain queries for your app to ensure that the needed functionality is achieved. Please ask your Swaarm account manager or partner developer for more information.

Did this answer your question?