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

# Import pledge card data for review

> Creates a pledge card review group from structured data. Rows enter the same donor matching and review workflow as scanned cards; this request does not create pledges.



## OpenAPI

````yaml /openapi.json post /api/v1/pledge-card-imports
openapi: 3.0.3
info:
  title: Grain API
  description: >-
    Church accounting and donor management API. Use an organization API key for
    server automation or OAuth 2.1 (Sign in with Grain) for applications acting
    on behalf of users. OAuth requests require X-Organization-Id; API keys infer
    it.
  version: 1.0.0
servers:
  - url: https://api.grainledger.com
    description: API Server
security:
  - ApiKeyAuth: []
  - GrainOAuth2: []
  - BearerAuth: []
tags:
  - name: Transactions
    description: Bank transactions and reconciliation
  - name: Bills
    description: Vendor bills from creation through payment
  - name: Donors
    description: Donor records and household relationships
  - name: Contributions
    description: Giving records with fund assignment and settlement
  - name: Pledges
    description: Pledge campaigns and fulfillment tracking
  - name: Pledge Card Imports
    description: Submit structured pledge card data for review
  - name: Households
    description: Household groupings and primary contacts
paths:
  /api/v1/pledge-card-imports:
    post:
      tags:
        - Pledge Card Imports
      summary: Import pledge card data for review
      description: >-
        Creates a pledge card review group from structured data. Rows enter the
        same donor matching and review workflow as scanned cards; this request
        does not create pledges.
      parameters:
        - $ref: '#/components/parameters/OrganizationId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePledgeCardImport'
            examples:
              annualCampaign:
                value:
                  scanGroupId: CMRC90
                  defaultRockAccountId: '101'
                  cards:
                    - externalId: '882145'
                      rockPersonId: '34567'
                      rockAccountId: '204'
                      rockCampusId: '3'
                      donorFirstName: Sarah
                      donorLastName: Johnson
                      donorEmail: sarah@example.org
                      amount: 12000
                      frequency: MONTHLY
                      startDate: '2027-01-01'
                      endDate: '2027-12-31'
      responses:
        '201':
          description: Pledge card data imported for review
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PledgeCardImportResult'
        '400':
          description: Bad request (missing header or invalid input)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized (missing or invalid Bearer token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden (no access to organization or action)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Conflict (duplicate record)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: Request body exceeds 2 MB
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  parameters:
    OrganizationId:
      name: X-Organization-Id
      in: header
      required: false
      schema:
        type: string
      description: >-
        Required with OAuth access tokens. Optional with organization API keys;
        if supplied, it must match the key's organization.
      example: cm123abc456def
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 255
      description: >-
        A unique key for this import request. Retrying the same body with the
        same key returns the original import without creating duplicate rows.
      example: pledge-import-2027-annual-001
  schemas:
    CreatePledgeCardImport:
      type: object
      required:
        - cards
      properties:
        scanGroupId:
          type: string
          description: >-
            Existing pledge card scan group ID. When set, cards are added as a
            new batch in that group. campaignId is inherited; a supplied request
            default fund or Rock account overrides the group's default.
        name:
          type: string
          minLength: 1
          maxLength: 100
          example: 2027 annual pledge cards
          description: >-
            Required when scanGroupId is omitted. Becomes the new scan group
            name.
        defaultFundId:
          type: string
          description: >-
            Grain fund used when a card has no override. Required when
            scanGroupId is omitted unless defaultRockAccountId is supplied.
        defaultRockAccountId:
          type: string
          description: >-
            Exact Rock financial account used when a card has no override. Do
            not send with defaultFundId.
        campaignId:
          type: string
          description: >-
            Optional Grain pledge campaign ID. Ignored when scanGroupId is set;
            the group's campaign is used instead.
        pledgeAudience:
          type: string
          enum:
            - ADULT
            - STUDENT
          default: ADULT
        cards:
          type: array
          minItems: 1
          maxItems: 500
          items:
            $ref: '#/components/schemas/PledgeCardInput'
    PledgeCardImportResult:
      type: object
      required:
        - scanGroupId
        - batchId
        - reviewUrl
        - idempotentReplay
        - sourceFileAttachmentId
        - cardsImported
        - cardsSkipped
        - cardsWithIssues
        - duplicateCards
        - items
      properties:
        scanGroupId:
          type: string
        batchId:
          type: string
        reviewUrl:
          type: string
          format: uri
        idempotentReplay:
          type: boolean
        sourceFileAttachmentId:
          type: string
          description: Secured audit artifact ID; not a scanned card attachment
        cardsImported:
          type: integer
          minimum: 0
        cardsSkipped:
          type: integer
          minimum: 0
        cardsWithIssues:
          type: integer
          minimum: 0
        duplicateCards:
          type: integer
          minimum: 0
        items:
          type: array
          items:
            type: object
            properties:
              itemId:
                type: string
              externalId:
                type: string
                nullable: true
              rockPersonId:
                type: string
                nullable: true
              rockAccountId:
                type: string
                nullable: true
              sourceIdentityStatus:
                type: string
                nullable: true
                enum:
                  - PENDING
                  - MATCHED
                  - CONFLICT
                  - NOT_FOUND
              status:
                type: string
                enum:
                  - EXTRACTED
                  - SKIPPED
              issue:
                type: string
                nullable: true
              duplicateOfId:
                type: string
                nullable: true
    Error:
      type: object
      required:
        - message
      properties:
        message:
          type: string
          example: You do not have access to this organization.
    PledgeCardInput:
      type: object
      properties:
        externalId:
          type: string
          maxLength: 128
          example: card-1001
        rockPersonId:
          type: string
          maxLength: 128
          description: >-
            Current Rock Person.Id. Exact identity routing bypasses fuzzy donor
            matching.
        donorFirstName:
          type: string
          maxLength: 100
          example: Sarah
        donorLastName:
          type: string
          maxLength: 100
          example: Johnson
        donorEmail:
          type: string
          format: email
          maxLength: 255
          example: sarah@example.org
        donorPhone:
          type: string
          maxLength: 50
          example: +1 615 555 0100
        donorAddress:
          type: string
          maxLength: 255
          example: 100 Church Street
        donorAddress2:
          type: string
          maxLength: 255
          example: Suite 200
          description: >-
            Second street-address line. Grain joins both lines with one space
            for donor matching while preserving both in the import artifact.
        donorCity:
          type: string
          maxLength: 100
          example: Nashville
        donorState:
          type: string
          maxLength: 100
          example: TN
        donorZip:
          type: string
          maxLength: 20
          example: '37201'
        amount:
          type: number
          minimum: 0
          example: 12000
        frequency:
          type: string
          enum:
            - ONE_TIME
            - WEEKLY
            - BIWEEKLY
            - MONTHLY
            - QUARTERLY
            - ANNUALLY
          example: MONTHLY
        fundId:
          type: string
          description: Optional per-card Grain fund ID. Do not send with rockAccountId.
        rockAccountId:
          type: string
          maxLength: 128
          description: >-
            Exact Rock financial account ID for this card. Do not send with
            fundId.
        fundName:
          type: string
          maxLength: 200
          description: >-
            Informational label shown during review. It is never used for fund
            routing or fallback.
        campusId:
          type: string
          deprecated: true
          description: Legacy internal Grain campus ID. Do not send with rockCampusId.
        rockCampusId:
          type: string
          maxLength: 128
          description: >-
            Exact Rock campus ID resolved through the integration campus
            catalog. Campus does not select a financial account.
        campusName:
          type: string
          maxLength: 200
          description: >-
            Legacy campus label used by the existing review matcher. Use
            rockCampusId for exact routing.
        startDate:
          type: string
          format: date
          example: '2027-01-01'
        endDate:
          type: string
          format: date
          example: '2027-12-31'
        notes:
          type: string
          maxLength: 2000
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: grain_live_… or grain_test_…
      description: >-
        Organization API key created in Grain Settings → API. The key determines
        the organization and is limited to its assigned resource scopes. Write
        scopes imply the corresponding read scope.
    GrainOAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://pqnoojlycpbwbatbdgep.supabase.co/auth/v1/oauth/authorize
          tokenUrl: https://pqnoojlycpbwbatbdgep.supabase.co/auth/v1/oauth/token
          scopes:
            openid: OpenID Connect
            email: Email address
            profile: Profile information
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: OAuth access token (JWT)

````