Last updated: January 6

<span aria-hidden="true" id="lets-build-ai-business-card-scanner-with-transloadit"></span>

# Let's Build: AI business card scanner with Transloadit

![Kevin van Zonneveld](/assets/images/teammates/avatar-kvz-4.jpg?dpl=dpl_AsMTCxwVXNuJ5TmdPevSCe63JuJo)

**Kevin van Zonneveld**

Co-founder · Amsterdam, The Netherlands · Show bio

[](https://x.com/kvz)[](https://github.com/kvz)

Business card scanners are a great example of productizing file workflows. You capture an image, clean it up, then extract contact details into structured fields. Transloadit’s primitives let you assemble that pipeline in a few steps.

<span aria-hidden="true" id="what-were-building"></span>

## What we’re building

* Accept PNG/JPEG or PDF cards
* Optimize images with [🤖 /image/optimize](/docs/robots/image-optimize.md)
* Extract contact fields with [🤖 /ai/chat](/docs/robots/ai-chat.md)

<span aria-hidden="true" id="schema-first-zod"></span>

## Schema first (zod)

```ts
import { z } from 'zod'
import { zodToJsonSchema } from 'zod-to-json-schema'

const businessCardSchema = z.object({
  full_name: z.string().optional(),
  title: z.string().optional(),
  company: z.string().optional(),
  email: z.string().optional(),
  phones: z.array(z.string()).optional(),
  address: z.string().optional(),
  website: z.string().optional(),
  socials: z.array(z.string()).optional(),
})

const toJsonSchema = (schema: z.ZodTypeAny): unknown =>
  typeof (z as { toJSONSchema?: typeof zodToJsonSchema }).toJSONSchema === 'function'
    ? (z as { toJSONSchema: typeof zodToJsonSchema }).toJSONSchema(schema)
    : zodToJsonSchema(schema)

const businessCardJsonSchema = toJsonSchema(businessCardSchema)

```

<span aria-hidden="true" id="pipeline-overview"></span>

## Pipeline overview

```
PDF cards  ──▶ /ai/chat
Images     ──▶ /image/optimize ──▶ /ai/chat

```

<span aria-hidden="true" id="assembly-snippet"></span>

## Assembly snippet

```ts
const assembly = await transloadit.createAssembly({
  params: {
    steps: {
      pdf_verified: {
        robot: '/file/filter',
        use: ':original',
        accepts: [['${file.mime}', '==', 'application/pdf']],
      },
      non_pdf: {
        robot: '/file/filter',
        use: ':original',
        accepts: [['${file.mime}', '!=', 'application/pdf']],
      },
      card_image: {
        robot: '/image/optimize',
        use: 'non_pdf',
        progressive: true,
      },
      extract_card: {
        robot: '/ai/chat',
        use: ['pdf_verified', 'card_image'],
        model: 'anthropic/claude-4-sonnet-20250514',
        format: 'json',
        schema: JSON.stringify(businessCardJsonSchema),
        messages: 'Extract business card fields. Omit keys if unknown.',
        result: true,
      },
    },
  },
  files: {
    card: filePath,
  },
  waitForCompletion: true,
})

```

<span aria-hidden="true" id="try-the-example-app"></span>

## Try the example app

The runnable version of this post lives at `example_apps/business-card-scanner/run.ts`.

```bash
node example_apps/business-card-scanner/run.ts

```

<span aria-hidden="true" id="suggested-inputs-for-visuals"></span>

## Suggested inputs for visuals

Use the bundled samples or swap in a real card scan:

* `_assets/demos/inputs/streetsign1.jpg`
* `_assets/demos/inputs/streetsign2.jpg`
* `_assets/demos/inputs/transloadit-padded.png`

<span aria-hidden="true" id="next-steps"></span>

## Next steps

* Add deduplication before inserting contacts into your CRM.
* Normalize phone numbers and addresses per locale.
* Add a manual review step for low-confidence extractions.

[#letsbuild](/blog/tags/letsbuild.md)[#ai](/blog/tags/ai.md)[#image-processing-service](/blog/tags/image-processing-service.md)[#artificial-intelligence-service](/blog/tags/artificial-intelligence-service.md)[#developer-experience](/blog/tags/developer-experience.md)

### 👩‍💻 Join 20k+ developers

Sign up for our [monthly newsletter](/newsletters.md) to receive direct links to 3 exclusive tech — and 2 product updates. No less, no more.

Your email:

Get access

## File uploading and encoding. Made simple.

Transloadit streamlines file handling for developers, trusted by brands like Coursera and The New York Times. We’re known for a reliable API, top-notch support, and a strong commitment to open source, with projects like [Uppy⁠](https://uppy.io) and [Tus⁠](https://tus.io) setting standards in file processing.

[Sign up](/c/)[Book a Demo](https://survey.typeform.com/to/kRg47Xi5)

No credit card needed

Cancel anytime
