How to Import JSON into WordPress: 4 Methods Compared (2026)
JSON is the default data format for nearly everything modern. REST APIs return it. Headless CMS platforms export it. SaaS tools, data pipelines, and mobile backends all speak JSON natively.
Yet most WordPress import guides still assume your data lives in a CSV or XML file. The top-ranking tutorials for "import JSON into WordPress" either teach you how to upload a .json file to the media library (that's file storage, not data import) or show custom AJAX code from 2015 that was never meant for production.
This guide covers four actual methods for importing JSON data into WordPress posts, custom fields, and WooCommerce products — with honest assessments of what each handles well and where each falls short.
First: "uploading" is not "importing"
This is the biggest source of confusion in existing guides.
Uploading a JSON file means adding it to the WordPress media library. WordPress doesn't allow .json uploads by default (security restriction on MIME types), so you'll find tutorials that add MIME type filters to upload_mimes. Once uploaded, the file sits in wp-content/uploads. Nothing happens to the data inside it.
Importing means parsing the JSON structure, mapping its fields to WordPress data types, and creating or updating posts, products, taxonomy terms, or custom field values in the database. The .json file is the input — the output is real WordPress content you can edit, query, and display.
Every method below handles actual importing.
Method 1: Custom PHP code
Cost: Free (your time) Best for: One-time developer migrations with simple, flat data
The most direct approach. Read the file, decode it, loop through records, and insert posts:
$json = file_get_contents( '/path/to/data.json' );
$records = json_decode( $json, true );
foreach ( $records as $record ) {
$post_id = wp_insert_post( [
'post_title' => sanitize_text_field( $record['title'] ),
'post_content' => wp_kses_post( $record['description'] ),
'post_status' => 'publish',
'post_type' => 'product',
] );
if ( ! is_wp_error( $post_id ) ) {
update_post_meta( $post_id, 'price', sanitize_text_field( $record['price'] ) );
update_post_meta( $post_id, 'sku', sanitize_text_field( $record['sku'] ) );
}
}
This works for flat JSON where every record has the same top-level keys. But it breaks down quickly:
- Nested objects require recursive handling. If your JSON has
"specs": {"weight": "2kg", "color": "red"}, you need to write custom logic to decide whether that becomes serialized meta, separate meta keys, or ACF sub-fields. - No batch processing. The script runs synchronously. 5,000 records means 5,000
wp_insert_post()calls in a single PHP execution — likely hitting memory or timeout limits. - No error recovery. If the script fails at record 3,412, you have no way to resume. You either re-run the entire import or manually track where it stopped.
- No GUI. Every new JSON shape requires rewriting the mapping logic. A non-developer can't adjust which source field maps to which WordPress field.
- ACF and WooCommerce need specific APIs.
update_post_meta()doesn't properly handle ACF repeaters (you needupdate_field()with field keys, not names). WooCommerce products need$product->set_regular_price()instead of raw meta updates, or you'll break price indexing.
Custom code is the right choice when you have a developer available, the JSON is flat, and you'll only run the import once.
Method 2: WP All Import
Cost: $199/yr (Import Pro Package) or $299/yr (with Export) Best for: Teams that primarily work with CSV/XML and occasionally need JSON
WP All Import is the most established WordPress import plugin, with over 100,000 active installs. It was originally built for CSV and XML — JSON support was added later and works by converting JSON to an internal XML representation.
For flat JSON arrays, this works smoothly. You upload your file, WP All Import detects the record structure, and you map fields using their drag-and-drop interface. The Import Pro Package bundles all framework add-ons (ACF, WooCommerce, JetEngine, MetaBox), so you don't need to buy them separately.
Where it gets harder:
- Nested JSON uses XPath notation. To reach
data.products[].specs.weight, you write an XPath expression like{specs/weight}. This works but requires understanding XPath syntax, which isn't intuitive for developers used to JavaScript dot notation — and is opaque to non-developers. - Deeply nested or variable-depth arrays are difficult to express in XPath. If your JSON has arrays of objects nested inside other arrays, the mapping expressions become complex.
- Export is a separate purchase. The $199/yr Import Pro Package only covers importing. If you also need to export WordPress data to JSON (for migration, backup, or syncing), you need the $299/yr package.
- No AI assistance. All field mapping is manual. For imports with 50+ fields, this is time-consuming.
WP All Import is a reliable choice when CSV and XML are your primary formats and JSON imports are occasional. The annual pricing adds up if you maintain multiple client sites.
Method 3: JSON Content Importer
Cost: Free / $199 (JCI Pro) Best for: Displaying external API data on WordPress pages
This is the plugin that causes the most confusion in search results, because the name suggests it imports JSON into WordPress. The free version doesn't.
JSON Content Importer (free) fetches JSON from a URL or API endpoint and displays it on your WordPress pages using shortcodes. It's a frontend display tool. The data is fetched and rendered on page load — nothing is saved to the WordPress database. If the API goes down, your page goes blank.
JCI Pro ($199 one-time) can create WordPress posts from JSON data. But the field mapping is limited to basic custom fields via update_post_meta(). It doesn't support ACF repeaters or field groups, JetEngine custom content types, MetaBox field groups, or WooCommerce product attributes through their native APIs.
If your goal is to show data from an external JSON API on a page — like pulling event listings or weather data — the free plugin handles that well. But if you need to actually import JSON records into your WordPress database with proper field framework support, this isn't the right tool.
Method 4: UMIE
Cost: Free / starting at €39/yr Best for: Complex or nested JSON targeting custom field frameworks
UMIE was built for JSON from the start. The parser uses halaxa/json-machine, a streaming JSON parser that processes files using PHP generators. This means O(1) memory usage regardless of file size — a 500MB JSON file uses the same memory as a 5KB one.
The import workflow:
- Upload or paste your JSON. UMIE detects the record structure automatically.
- Map fields visually. The Node View displays your source JSON as an interactive tree on the left and your WordPress destination fields on the right. You draw connections between them on a React Flow canvas. Nested objects appear as nested node groups — you can see the structure, not just a flat list.
- AI mapping suggestions (optional). Click one button and UMIE analyzes your source schema against your destination fields. Suggestions stream in via SSE with confidence scores. Accept the good ones, adjust the rest.
- Import. Records are batched and processed via Action Scheduler — WordPress's built-in background job runner. Row-level logging tracks success, failure, and retry status for every record.
UMIE ships with five drivers that handle the specific APIs each framework requires:
| Driver | What it handles |
|---|---|
| Native | wp_insert_post() + update_post_meta() for core WordPress fields |
| ACF | update_field() with field keys, repeaters, groups, flexible content |
| JetEngine | Custom content types (CCT tables), meta boxes, relations |
| MetaBox | rwmb_set_meta() with auto-routing for custom tables |
| WooCommerce | Product CRUD: $product->set_regular_price(), attributes, variations |
All drivers are included in every plan — including free. Export is also included in every plan.
The hard parts of JSON import
Regardless of which method you choose, JSON import into WordPress is genuinely harder than CSV import. Here's why.
Nested objects
CSV is flat by definition — every value lives in a column. JSON can nest objects inside objects inside arrays.
{
"name": "Running Shoe",
"specs": {
"weight": "280g",
"drop": "8mm",
"materials": {
"upper": "mesh",
"sole": "rubber"
}
}
}
Custom code needs recursive handling. WP All Import uses XPath: {specs/materials/upper}. UMIE shows this as a visual tree where you can map specs > materials > upper to an ACF sub-field by drawing a connection.
Repeater and array data
Many JSON sources contain arrays of objects — product images, specification rows, variant options:
{
"images": [
{"url": "front.jpg", "alt": "Front view"},
{"url": "side.jpg", "alt": "Side view"}
]
}
ACF repeaters require building the complete array and saving it in a single update_field() call. If you call add_row() in a loop instead, you get race conditions and corrupt data. WP All Import handles this through its ACF add-on. Custom code needs to build the array manually. UMIE's ACF driver handles array construction automatically.
Large files
A 10MB JSON file with 50,000 records will crash most import approaches that load the entire file into json_decode(). PHP's default memory limit is 128MB or 256MB — a 10MB JSON file can easily consume 500MB+ when decoded into PHP arrays.
WP All Import chunks files based on size limits. Custom code needs manual pagination. UMIE's streaming parser reads one token at a time, never holding the full file in memory.
Relational data
Posts that reference other posts — like a book that references its author, or a product that references related products — need a two-pass import. First pass: create all records and track old ID → new ID mappings. Second pass: update relational fields with the new IDs.
This is hard to implement correctly in custom code, partially supported by WP All Import (via their "Record Matching" feature), and handled natively by UMIE's import worker.
Comparison table
| Feature | Custom Code | WP All Import | JSON Content Importer | UMIE |
|---|---|---|---|---|
| Price | Free | $199–299/yr | Free / $199 | Free / €39/yr |
| JSON-native | No (manual parsing) | No (converts to XML) | Yes (display only) | Yes (streaming parser) |
| Visual field mapping | No | Linear drag-drop | No | React Flow canvas |
| AI mapping suggestions | No | No | No | Yes |
| Nested JSON handling | Manual recursion | XPath notation | Basic | Visual tree mapping |
| ACF repeaters | Manual code | Via add-on (included) | No | Native driver |
| WooCommerce products | Manual code | Via add-on (included) | No | Native driver |
| Large file support | Memory-limited | File chunking | API-dependent | Streaming (O(1) memory) |
| Background processing | No (synchronous) | Yes | No | Yes (Action Scheduler) |
| Export included | N/A | +$100/yr add-on | No | Yes (all plans) |
Which method should you use?
Simple flat JSON, one-time import, developer available → Custom PHP code. Write it, run it, delete it. No plugin needed.
CSV and XML are your primary formats → WP All Import. It's battle-tested for those formats. JSON support works for flat structures through the XPath interface.
You need to display external API data on pages → JSON Content Importer (free). It does this one thing well with shortcodes.
Complex or nested JSON targeting ACF, JetEngine, MetaBox, or WooCommerce → UMIE. It was built for this exact use case — streaming JSON parser, visual mapping canvas, five native drivers, AI suggestions.
Getting started
UMIE's free plan includes the Native driver, all five views (Node, Table, AI Import, Image, Export), and 10,000 AI tokens — enough to test AI mapping suggestions on several real imports. No credit card required.
Install from umie.pro, upload a JSON file, and see your data structure on the visual canvas. If the free plan covers your needs, keep using it. If you need ACF, JetEngine, MetaBox, or WooCommerce drivers, paid plans start at €39/yr for a single site.