API Cookbook — Bulk Operations

Bulk Create (up to 500 records)

Use bulkcreate instead of looping create — it's dramatically faster.

curl -s -k -X POST "https://wherewelearn.com/api/apic.php" \
  -d "u=myuser&k=mykey&r=COLLREF&g=WRITEVIEWID&f=bulkcreate" \
  --data-urlencode 'records=[
    {"strD5_1_1":"First item","strD5_1_6":"Development"},
    {"strD5_1_1":"Second item","strD5_1_6":"Bug"},
    {"strD5_1_1":"Third item","strD5_1_6":"Governance"}
  ]'

Response: {“fnerr”:0,“total”:3,“created”:3,“failed”:0,“results”:[…]}

Each result entry: {“index”:0,“dxid”:1236,“fnerr”:0}

Bulk Create from a CSV (Python)

import csv, json, requests
 
API_URL = 'https://wherewelearn.com/api/apic.php'
AUTH    = {'u': 'APIUSER', 'k': 'APIKEY', 'r': 'COLLREF', 'g': 'WRITEVIEWID'}
 
# Map CSV column headers to collection field columns
FIELD_MAP = {
    'Title':    'strD5_1_1',
    'Area':     'strD5_1_6',
    'Priority': 'strD5_1_25',
}
 
def csv_to_records(filepath):
    with open(filepath) as f:
        return [
            {FIELD_MAP[k]: v for k, v in row.items() if k in FIELD_MAP}
            for row in csv.DictReader(f)
        ]
 
def bulk_create(records, batch_size=500):
    for i in range(0, len(records), batch_size):
        batch = records[i:i+batch_size]
        r = requests.post(API_URL, data={**AUTH, 'f': 'bulkcreate',
                                          'records': json.dumps(batch)}, verify=False)
        data = r.json()
        print(f"Batch {i//batch_size+1}: created {data['data']['created']}, failed {data['data']['failed']}")
 
bulk_create(csv_to_records('items.csv'))

Bulk Status Update

To close all records matching a filter (e.g. mark all “Development” items complete):

import requests
 
API_URL = 'https://wherewelearn.com/api/apic.php'
AUTH    = {'u':'APIUSER','k':'APIKEY','r':'COLLREF'}
 
# Step 1: get all open development records
r = requests.post(API_URL, data={**AUTH,'g':'8','f':'crosslist',
                                  'dxField':'strD5_1_6','dxValue':'Development',
                                  'per_page':'500'}, verify=False)
records = r.json()['data']['records']
 
# Step 2: close each one
for rec in records:
    rid = rec['intD5_Id']
    requests.post(API_URL, data={**AUTH,'g':'WRITEVIEWID','f':'update',
                                  'dxId':rid,'strD5_1_5':'True',
                                  'notes':'Bulk closed via API'}, verify=False)
    print(f"Closed record {rid}")