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

# Offline check-in APIs

> Integrate Douyin and REDnote offline check-ins for anonymous users who publish in the platform app after scanning a QR code.

The offline check-in APIs are called by an integration partner that owns an API key. The person scanning the QR code does not need an AiToEarn account and does not need to bind a Douyin or REDnote account in advance.

## Participants

| Participant         | Responsibility                                                            |
| ------------------- | ------------------------------------------------------------------------- |
| Integration backend | Store the API key, call AiToEarn Open APIs, and maintain business records |
| Integration page    | Display a QR code or mobile sharing page                                  |
| Scanning user       | Scan anonymously and confirm publishing in the platform app               |
| AiToEarn            | Generate platform launch parameters and track results where supported     |

## Douyin flow

<Steps>
  <Step title="Create a publish entry">
    Call `POST /api/v2/channels/douyin/open/offline-qr` from the integration backend with `X-Api-Key`.
  </Step>

  <Step title="Display the QR code">
    Store `recordId`. Either display `userAction.qrCodeUrl` directly or generate your own QR code from `userAction.shortLink`. Never expose the API key to the frontend.
  </Step>

  <Step title="Let the user publish">
    The user scans the QR code on a phone. The short link opens Douyin with the title, body, and media prefilled, and the user confirms publishing.
  </Step>

  <Step title="Query the result">
    Using the same API key that created the record, call the existing `GET /api/v2/channels/publish/records/{recordId}` endpoint from the integration backend.
  </Step>
</Steps>

The API supports two QR code display options:

* `qrCodeUrl`: A server-generated PNG Data URL that can be used directly in an HTML `<img>` element.
* `shortLink`: An HTTPS short link that the integration can encode into a custom QR code with its preferred size, colors, styling, or logo.

To display the generated QR code directly:

```html theme={null}
<img src="<qrCodeUrl>" alt="Douyin offline check-in QR code" />
```

Both options ultimately encode `shortLink`. `schemeUrl` can be used by a mobile page to attempt to open the Douyin App directly.

`status: 8` means that user action is still required. It does not mean that publishing succeeded.

| status | Meaning                        | Action                                             |
| -----: | ------------------------------ | -------------------------------------------------- |
|    `8` | Waiting for the user in Douyin | Keep displaying the QR code and query periodically |
|    `1` | Published                      | Store `workLink`                                   |
|   `-1` | Failed or expired              | Inspect `error` and create a new entry if needed   |

After publishing completes, AiToEarn updates the publish record from the Douyin webhook. Query every 5–10 seconds and stop after `expiresAt`. Create a new entry after the link expires.

```bash theme={null}
curl "https://aitoearn.ai/api/v2/channels/publish/records/<recordId>" \
  -H "X-Api-Key: <YOUR_API_KEY>"
```

## REDnote flow

The REDnote endpoint returns a signature for `xhs.share`. It does not create an AiToEarn publish record or return the final post result.

<Steps>
  <Step title="Prepare a mobile landing page">
    Provide your own mobile sharing page and encode that page URL as the offline QR code.
  </Step>

  <Step title="Request the signature">
    After the page opens, call `POST /api/v2/channels/rednote/open/offline-qr/share-config` from your backend. Keep the API key on the server.
  </Step>

  <Step title="Call xhs.share">
    Use the returned `verifyConfig` in the frontend call to `xhs.share`, together with the title, body, images, or video.
  </Step>

  <Step title="Let the user share">
    The user confirms publishing in the REDnote app. A frontend callback only indicates the `xhs.share` invocation or app-launch result and must not be treated as final publishing confirmation.
  </Step>
</Steps>

### Backend proxy

The QR landing page must not call AiToEarn with the API key directly. It should call the integration backend, which requests the signature from AiToEarn and returns `verifyConfig` to the page.

```ts theme={null}
async function getRedNoteShareConfig() {
  const response = await fetch(
    'https://aitoearn.ai/api/v2/channels/rednote/open/offline-qr/share-config',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Key': '<YOUR_API_KEY>',
      },
      body: JSON.stringify({}),
    },
  )

  if (!response.ok) {
    throw new Error('Failed to get the REDnote signature')
  }

  const result = await response.json()
  return result.data.verifyConfig
}
```

`nonce` is optional and can be generated by AiToEarn. If the integration supplies its own `nonce`, it must use the returned `nonce`, `timestamp`, and `signature` together and must not mix fields from different requests.

### Use the signature on the landing page

After obtaining `verifyConfig` from the integration backend, pass it unchanged to REDnote `xhs.share`. The title, body, images, or video are not sent to the AiToEarn signature endpoint; pass them when calling `xhs.share` using the parameter format required by the REDnote SDK version used by the integration.

```js theme={null}
const response = await fetch('/api/checkin/rednote/share-config', {
  method: 'POST',
})
const { verifyConfig } = await response.json()

// Pass verifyConfig unchanged to xhs.share.
// Build the sharing-content fields for the REDnote SDK version in use.
```

Request a signature when the user is ready to share. Do not cache it for a long time or reuse it across multiple sharing attempts. AiToEarn does not create a REDnote publish record, so there is no `recordId` and no publish-record polling step.

<Note>
  A successful `xhs.share` callback only confirms the SDK invocation or app launch. The user may still cancel instead of publishing in the REDnote app.
</Note>

<Warning>
  Douyin returns a ready-to-display QR code. REDnote returns a frontend sharing signature. These are different publishing protocols and require different integration flows.
</Warning>
