> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gameball.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Manual Transaction

> Add manual point adjustments to customer accounts.

## Add Manual Transaction

This API allows for the manual addition or deduction of points for a customer in Gameball. It provides flexibility in managing loyalty points, enabling adjustments based on specific needs or circumstances.

This endpoint is also available on `v4.1`.

<Info>
  **Channel Merging Available**
  If your system uses different customer IDs across multiple channels (e.g., online and offline), Gameball's channel merging feature helps unify customer profiles. By including the customer's mobile number or email (based on your merging configuration) with each request, Gameball will combine activities into a single profile.
</Info>

<Info>
  Security: Provide both `apikey` and `secretkey` headers.
</Info>

### Custom Points Expiry

Use `expiryAfter` to set a custom expiry period for points added through a manual transaction. The value is the number of days after which the added points expire, counted from the time the points are credited. For example, `30` means the awarded points expire 30 days from the time of the addition.

When `expiryAfter` is omitted, sent as `null`, or sent as `0`, the points follow the client's default points-expiry setting configured in the dashboard. This matches the custom expiry option available when manually adding points from the Gameball dashboard.

<Warning>
  `expiryAfter` applies only to point additions. Do not send it with a deduction, such as a negative `points` or `amount` value.
</Warning>

### Validation

| Condition                                                                       | Result                                               |
| ------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `expiryAfter` is negative                                                       | `400` - `Expiry cannot be negative`                  |
| `expiryAfter` is provided on a deduction, such as negative `points` or `amount` | `400` - `Deduction cannot have expiry`               |
| Both `points` and `amount` are provided                                         | `400` - `Only one rewarding method may be specified` |
| Neither `points` nor `amount` is provided                                       | `400` - `A rewarding criteria is required`           |

### Example: Add Points With Custom Expiry

```bash theme={null}
curl -X POST "https://api.gameball.co/api/v4.0/integrations/transactions/manual" \
  -H "Content-Type: application/json" \
  -H "APIKey: <YOUR_API_KEY>" \
  -H "secretkey: <YOUR_SECRET_KEY>" \
  -d '{
    "customerId": "player-123",
    "transactionId": "manual-0001",
    "transactionTime": "2026-06-01T12:00:00Z",
    "username": "ops.admin",
    "reason": "Goodwill credit",
    "points": 500,
    "expiryAfter": 30
  }'
```

In this example, the customer is credited `500` points that expire 30 days from the time of the addition.

### Example: Use the Client Default Expiry

```json theme={null}
{
  "customerId": "player-123",
  "transactionId": "manual-0002",
  "username": "ops.admin",
  "reason": "Goodwill credit",
  "points": 500
}
```

In this example, `expiryAfter` is omitted, so the credited points follow the client's default points-expiry configuration.


## OpenAPI

````yaml POST /api/v4.0/integrations/transactions/manual
openapi: 3.1.0
info:
  title: Gameball API
  description: >-
    Gameball REST API v4.0 - Complete API reference for integrating loyalty,
    gamification, and customer engagement features
  version: 4.0.0
servers:
  - url: https://api.gameball.co
security:
  - bearerAuth: []
paths:
  /api/v4.0/integrations/transactions/manual:
    post:
      description: >-
        This API allows for the manual addition or deduction of points for a
        customer in Gameball. It provides flexibility in managing loyalty
        points, enabling adjustments based on specific needs or circumstances.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - customerId
                - transactionId
                - username
                - reason
              properties:
                customerId:
                  type: string
                  description: >-
                    Unique identifier for the customer that you can reference
                    across the customer's whole lifetime. Could be a database
                    ID, random string, email, or anything that uniquely
                    identifies the customer.
                  example: cust_abc12345xyz67890
                email:
                  type: string
                  description: >-
                    Customer's email address. This is required if your account
                    uses email-based channel merging.
                  example: john.doe@example.com
                mobile:
                  type: string
                  description: >-
                    Customer's mobile number. This is required if your account
                    uses mobile-based channel merging.
                  example: '+1234567890'
                transactionId:
                  type: string
                  description: >-
                    A unique identifier for a transaction in your system (e.g.,
                    order number or invoice number). This ID can be used to
                    reverse, cancel, or refund any reward or redemption
                    transactions in Gameball.
                  example: txn543211
                transactionTime:
                  type: string
                  format: date-time
                  description: >-
                    The time of the transaction in your system (e.g., order
                    datetime, invoice datetime). Defaults to the current time in
                    UTC when omitted.
                  example: '2024-10-11T15:54:10.944Z'
                username:
                  type: string
                  description: The username of the admin performing the manual transaction.
                  example: admin_user
                reason:
                  type: string
                  description: >-
                    Reason for manually rewarding or deducting points (e.g.,
                    'Referral bonus').
                  example: Referral bonus
                points:
                  type: integer
                  description: >-
                    The number of points to be rewarded or deducted. Provide
                    either points or amount. Positive values add points, and
                    negative values deduct points.
                  example: 50
                amount:
                  type: number
                  description: >-
                    The monetary value, in system currency, associated with the
                    transaction. Provide either points or amount. Positive
                    values add points, and negative values deduct points.
                  example: 0
                expiryAfter:
                  type: integer
                  minimum: 0
                  nullable: true
                  description: >-
                    The number of days after which the points added in this
                    transaction will expire, counted from the time of the
                    addition. For example, 30 means the awarded points expire 30
                    days from now. When omitted, null, or 0, the points follow
                    the client's default points-expiry setting configured in the
                    dashboard. This replicates the custom-expiry option
                    available when manually adding points from the Gameball
                    dashboard. expiryAfter applies only to point additions; it
                    cannot be used when deducting points.
                  example: 30
      responses:
        '200':
          description: Manual transaction added successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  customerId:
                    type: string
                    description: >-
                      Unique identifier for the customer that you can reference
                      across the customer's whole lifetime. Could be a database
                      ID, random string, email, or anything that uniquely
                      identifies the customer.
                    example: cust_abc12345xyz67890
                  gameballTransactionId:
                    type: number
                    description: The unique identifier for the transaction within Gameball.
                    example: 11035201
                  transactionId:
                    type: string
                    description: >-
                      A unique identifier for a transaction in your system
                      (e.g., order number or invoice number). This ID can be
                      used to reverse, cancel, or refund any reward or
                      redemption transactions in Gameball.
                    example: txn54321221
                  points:
                    type: number
                    description: >-
                      The number of points rewarded or deducted in the
                      transaction.
                    example: 50
                  amount:
                    type: number
                    description: The monetary value processed in the transaction.
                    example: 5
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                negativeExpiry:
                  summary: Negative expiryAfter
                  value:
                    error: 400
                    message: Expiry cannot be negative
                deductionWithExpiry:
                  summary: expiryAfter on a deduction
                  value:
                    error: 400
                    message: Deduction cannot have expiry
                multipleRewardingMethods:
                  summary: Both points and amount provided
                  value:
                    error: 400
                    message: Only one rewarding method may be specified
                missingRewardingCriteria:
                  summary: Neither points nor amount provided
                  value:
                    error: 400
                    message: A rewarding criteria is required
      security:
        - apiKey: []
          secretKey: []
components:
  schemas:
    Error:
      required:
        - error
        - message
      type: object
      properties:
        error:
          type: integer
          format: int32
        message:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    apiKey:
      type: apiKey
      in: header
      name: apikey
    secretKey:
      type: apiKey
      in: header
      name: secretkey

````