Payhawk → Google Drive receipt sync avatar

Payhawk → Google Drive receipt sync

Pricing

Pay per usage

Go to Apify Store
Payhawk → Google Drive receipt sync

Payhawk → Google Drive receipt sync

Automatically archive Payhawk expense receipts (PDFs) to a Google Drive folder. Incremental, idempotent, schedule-friendly — every new receipt lands in Drive without duplicates.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Apify

Apify

Maintained by Apify

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

9 days ago

Last modified

Categories

Share

Payhawk → Google Drive Receipt Sync

Automatically archive Payhawk expense receipts (PDFs) to a Google Drive folder. Set it on a schedule and only new receipts get uploaded, without duplicates.

What is the Payhawk Google Drive Receipt Sync?

The Actor takes every expense receipt PDF from your Payhawk account and saves it to a Google Drive folder of your choice. Set it up once, run it on a schedule, and you stop downloading PDFs one expense at a time. Every new receipt your colleagues add to Payhawk shows up in Drive, ready to hand off to your accountant, feed into your bookkeeping system, or keep on file for long-term archival.

Behind the scenes, the Actor uses Payhawk's official Developer API to pick up only the receipts that haven't been exported yet, drops them into Drive, and marks them as exported in Payhawk. The same receipt never gets uploaded twice.

What it can do?

  • Sync only what's new. Each run picks up the receipts that haven't been exported yet and skips everything you've already moved.
  • Never upload the same receipt twice. Files use a predictable name based on the expense ID, so if a receipt is already in Drive, the Actor leaves it alone.
  • Handle expenses with multiple receipt pages. When an expense has two or more attachments, each one ends up in Drive as its own numbered file.
  • Keep Payhawk's record straight. Once a receipt is in Drive, the Actor marks the expense as exported in Payhawk, so your team can see at a glance which receipts have already been sent.
  • Test before you flip the switch. Dry-run mode walks through the whole sync without writing anything to Drive, so you can confirm permissions, folders, and credentials are right.
  • Hand back a full audit log. Every run produces a dataset where each row shows what happened to one expense: success, skip, missing receipt, or error.
  • Schedule, monitor, and connect. Running on Apify means you can set the sync to run daily, watch for failures, plug into your other tools, and pull results from the Apify API whenever you need them.

How does it work?

Every run follows the same five steps:

  1. Asks Payhawk for new expenses. The Actor pulls the list of expenses that haven't been exported yet and are older than the sync lag (no lag by default), page by page.
  2. Downloads each receipt. For every expense it finds, the Actor grabs each attached PDF.
  3. Uploads the PDFs to Drive. Receipts go into the Google Drive folder you configured. The folder has to live inside a Shared Drive so the service account has permission to write to it.
  4. Marks the expense as exported in Payhawk. The Actor writes an entry to Payhawk's export history, including a link back to the file in Drive.
  5. Keeps a local memory of what's already been synced. Each processed expense ID is stored in an Apify key-value store as a safety net against accidentally uploading the same receipt twice.

How much will it cost?

The Actor runs on Apify and bills by compute units. Since most of each run is just waiting for Payhawk and Google Drive to answer, the work isn't compute-heavy. A run handling a few hundred receipts uses a small fraction of one compute unit, so the free Apify tier is usually enough to try the Actor on a real month of expenses.

The Payhawk and Google Drive APIs the Actor talks to are both free to use within their published rate limits. Payhawk caps its developer API at 15 requests per second, well above anything the sync gets close to.

How to set up Payhawk to Google Drive Receipt Sync

Step 1: Get your Payhawk API key

In Payhawk, go to Settings → Integrations → API → Create key. Copy the key (it is sent in the X-Payhawk-ApiKey header). The account ID is shown alongside the key and also appears in any Payhawk URL.

Put the values into payhawkApiKey and payhawkAccountId.

Step 2: Create a Google service account

Service accounts are how a long-running Actor can write to Drive without an interactive Google login.

  1. In the Google Cloud Console: IAM & Admin → Service Accounts → Create service account. Any name works (e.g. payhawk-sync).
  2. Open the new service account → Keys → Add key → Create new key → JSON. Save the downloaded JSON; you will paste it into googleServiceAccount.
  3. In APIs & Services → Library, search for and enable the Google Drive API for the project.

Step 3: Create a Shared Drive folder and share it with the service account

This step is required. Service accounts have no storage quota in a personal My Drive. Uploads to a regular My Drive folder fail with Service Accounts do not have storage quota. A Shared Drive is the supported way to give a service account a place to write.

  1. In Google Drive, open the left sidebar → Shared drives → + New. Name the drive anything you like (for example, Payhawk receipts).
  2. Inside the Shared Drive, create a folder for the receipts.
  3. Open the Shared Drive → Manage members → add your service account's email (xxx@<project>.iam.gserviceaccount.com, found in the JSON you downloaded) with the Content manager role.
  4. Open the destination folder and copy the ID from the URL: drive.google.com/drive/folders/<id>. Paste it into driveFolderId.

Step 4: Run with dry-run enabled

For the first run, set dryRun to true. The Actor will list expenses and download receipts but will not write to Drive or Payhawk. Confirm the logs look right (e.g. the expected number of expenses are found), then flip dryRun to false and run for real.

Step 5: Schedule it

Once a real run succeeds, create an Apify schedule at the cadence you want (daily and hourly are common choices).

Input

The Actor takes the following inputs. See the Input tab for the full schema with descriptions and secret handling.

  • payhawkApiKey: Payhawk API key.
  • payhawkAccountId: Payhawk account ID.
  • googleServiceAccount: Service account JSON for Google Drive access.
  • driveFolderId: Destination Drive folder ID. Must live inside a Shared Drive.
  • exportedInto (optional): Label written to Payhawk's export history. Defaults to "Google Drive".
  • syncLagDays (optional): Only sync expenses created at least this many days ago, giving your team time to attach or fix a receipt first. Defaults to 0 (sync immediately with no lag). Set e.g. 7 to wait a week.
  • dryRun (optional): When true, the Actor skips all writes. Defaults to false.

Output

The Actor writes one dataset row per processed expense, with the upload status and a link to the file in Drive. You can download the dataset in JSON, CSV, Excel, HTML, RSS, or XML, the same as any Apify Actor.

Status values: uploaded, reused (file already existed in Drive), skipped-already-synced (already in local dedupe state), no-receipt (expense had no attached document), missing-id (malformed expense with no ID), and error.

FAQ

Why does the upload fail with "Service Accounts do not have storage quota"?

The destination folder is in a personal My Drive instead of a Shared Drive. Service accounts can be granted access to a My Drive folder, but they cannot own files there, and Drive will refuse the upload. Move the folder into a Shared Drive (see Step 3 above) and use that folder ID instead.

Can I sync to a personal My Drive folder?

Not with a service account. The alternative is OAuth domain-wide delegation, which makes the service account impersonate a Google Workspace user, so uploaded files use that user's quota. This requires a Google Workspace administrator to grant the delegation. Most teams find creating a Shared Drive easier.

Will running the Actor twice create duplicate files in Drive?

No. The Actor checks for an existing file with the same payhawk-<expenseId>.pdf name in the destination folder before uploading, and it only requests expenses that haven't already been exported into this destination. As an extra safety net, synced expense IDs are tracked in a named key-value store.

What happens to expenses without an attached receipt?

They are reported as no-receipt in the dataset and skipped. The expense is not marked as exported in Payhawk, so it will be re-evaluated on the next run, giving your team a chance to upload the receipt.

What if someone adds or changes a receipt after the expense is created?

That is what the syncLagDays input is for. By default it is 0, so expenses sync immediately. Set it to, say, 7 and the Actor will only sync expenses created at least that many days ago, giving your team a window to attach or correct a receipt before it is exported to Drive. Note that once an expense has been synced, changing its receipt in Payhawk later will not re-upload it, because the file already exists in Drive under the same name.

Is this a two-way sync?

No. The Actor syncs one-way, from Payhawk to Google Drive. Files deleted from Drive are not re-uploaded on the next run, because the expense has already been marked as exported in Payhawk.

How do I change the label that appears in Payhawk's export history?

Set the exportedInto input. It defaults to "Google Drive". During testing, change it to something like "Test sync" so test runs are clearly distinguishable from real ones in Payhawk's UI.

How do I run the Actor locally?

Clone the repo, run npm install, put your inputs in storage/key_value_stores/default/INPUT.json, then run npx apify run. Use dryRun: true to validate the setup without touching Drive or Payhawk.