Table of Contents
Motivation
What You Need
APIs vs Webhooks
Basic Postman Setup
Authentication & Base URL
Types of API Requests
Testing your Environment
Building an API Request
The Runner
Debugging Requests
Where do I go from here?
Caveats and Considerations
Motivation
Workflows can do many automated things in the CRM, but they are intended to be "point and click" and do not offer all of the functionality that's possible in terms of automating the CRM, nor are the workflows as customizable as working directly with the CRM API.
As such, this guide is a starting point for working with the CRM API to accomplish things that workflows are unable to do, or to accomplish such automations in a more customized way.
While many in this day and age may use AI agents to write API code for them, it's still useful to know how all of the parts and pieces work, because there will inevitably be debugging to do. This guide is therefore a manual / "from scratch" example of how to work with the CRM webhooks and API, without any sort of AI assistance.
What You Need
Firstly, it's a good idea to have Postman, or a similar tool available for testing.
https://postman.com
https://www.fosshub.com/Postman-old.html
Postman is a commercial software but the second link above is to an older non-cloud-enabled version of it. If you prefer the free version, use that link to download it and ignore any upgrade prompts within the application.
Postman is like a web browser for APIs. It allows you to make pre-configured API requests which can be saved like bookmarks in your web browser.
It's also not a bad idea to have a programming text editor. Visual Studio Code from Microsoft is also free to use, and is downloadable from either the Windows or Apple app stores.
https://code.visualstudio.com/
Why a programming editor? In short, the color codes and highlights, as the screenshot on the application's homepage shows. If you've never used a programming text editor before, these are essential functions that something like Notepad or TextEdit cannot do. The programming editor will know what type of language you are working with and will highlight errors for you, making them easy to locate and correct.
Lastly, you'll want to have some sort of tool that can receive webhooks from the CRM so you can examine them for testing purposes.
https://pipedream.com is a good tool to use for this purpose. You can do many things on this service, but on the free tier you can have one listener that you can send webhooks to, and then examine the data in the pipedream website or copy it out to Visual Studio Code to examine in an editor.
Speaking of webhooks...
APIs vs Webhooks
There are two types of things in play for most integrations with external services, as far as the CRM is concerned, Webhooks and the CRM API.
Webhook: the thing calls you, and says "this has happened, and here's the data from this thing"
API: you call the thing, and say "put this data in, or give me this data back"
In short, you'll probably have a webhook trigger your external integration, by having the CRM call it and give it data when something happens. This can be when any type of data (account, transaction, membership, etc) is created or updated, for example.
Then, your integration would use the API to do all of its other tasks that you want done. Webhooks are one-way communications, the system calls the external service, gives it the data, then hangs up. APIs are two way communications, the external system takes data from you via an API request, does what action you specify, and then returns a confirmation that the action was completed, or if there's an error, what the error is.
Basic Postman Setup
When you open Postman for the first time, you'll see a welcome screen like this one (and probably one of those upgrade offers like the one mentioned above, which you can just ignore out of).
Postman basically works like a web browser, API requests show up as tabs in the middle of the app, and the left hand side of the app shows your "collections", which are like bookmarked API requests that you can select and run in a tab in the main part of the application.
So the first thing you can do once you're up and running is to install the reference for all of the Neon API v2 requests in your "collections" bookmarks in the application.
If you go to the Neon API v2 documentation page, you'll see a yaml link at the top. Yaml is a simple template language, very similar in format to the custom import rules we write for data migrations, which is commonly used to define API configurations by punctuation and indentation. Since Postman can read yaml API reference files, you can simply download the Neon CRM API v2 yaml reference from the developer site, and import it directly into Postman to get all of the documented Neon CRM API v2 requests into the application.
https://developer.neoncrm.com/api-v2/
Once you've downloaded the yaml file, simply go to file, import and import it into Postman...
...like so...
After doing this, you should have all of the Neon v2 API requests loaded up in your collection sidebar on the left side of the app, like this:
Authentication & Base URL
Next, you should open up the settings on the Neon CRM API Reference that you just imported, via its 3-dot context menu, and edit the settings for the collection, like so:
From here, select the authorization tab and change the default to "basic" like this, including the variable references in curly brackets for the username and password, more on that as we go:
Next, we need a new environment variable pool to store the username and password in. Do not make a habit of putting credentials like usernames and passwords into API requests, or code that generates API requests!
The above is very important, your API key is basically a master password to your CRM, if someone besides you gets that API key, they have full control of your database. Don't email API keys, don't put them in code you write, and don't give them to AI agents. It's always a best practice to save them as a temporary variable.
Postman allows you to create variables to hold your API credentials, they are called Environments. To make one, click "Manage Environments" menu next to the "eye" icon at the upper right hand corner of the app.
After doing so, make yourself an environment, which you can name whatever you like. You can use one environment over and over, copying and pasting credentials if you need to change them, or you can make multiple environments and use a dropdown to toggle between them if you use multiple APIs at the same time, this is really up to you.
The environment settings are used to define variables, which are used like email tokens are in the CRM, to hold usernames, passwords, session tokens, and other such things that must be repeated for each API request.
After you've made a new environment, open its settings by clicking the "eye" icon next to the last one you clicked, which should say "environment quick look" when you hover over it.
In the case of the Neon CRM APIs, there are three variables you should set in your environment.
- The baseUrl of the API you're using.
-
The basicAuthUsername which in our case is the organization ID of the CRM you're working with, in simpler terms: the username. This matches the {{basicAuthUsername}} variable we put into the CRM API Reference settings above.
- The basicAuthPassword which is your API key for working with that instance, in other words: the password, also matching the {{basicAuthPassword}} variable we put into the CRM API Reference above.
To define these, simply set them by name in the column on the left of the Environment editing tool, with the values on the far right "CURRENT VALUE" column, like so:
The base URL we got from the Neon CRM developer site's API documentation, in the screenshot above from where we downloaded the YAML file. You can retrieve your username / Organization ID from the settings wheel in your CRM, under "Organization Profile, like so:
And you can retrieve your API key (password) from your user account in the CRM by clicking on your name under the settings wheel -> user management, like so:
NOTE: You should name API user accounts in user CRMs descriptively. It's a good idea to set up a separate admin user with something obvious like first name = "Api" and last name = "Account", and use a generic email that multiple people can log into to retrieve things. You don't want all of your automations built around a user in the CRM that will need to be disabled if that user leaves the organization for a new job, for example.
To test our environment setup, we could simply run a non-modifying request to make sure it works. Which brings us to... types of requests.
Types of API Requests
Broadly speaking you're going to come across these types of API requests.
-
GET: get something from the server, this doesn't change any data, it just retrieves it
-
POST: put something on the server, this changes data, by creating a new record
-
PATCH: modify something on the server, this changes data, but modifies an existing record rather than creating a new one
-
PUT: create or replace something on the server, this changes data, by creating or replacing the record you specify
- DELETE: self explanatory. If you can create a thing, you can probably also destroy that thing with a DELETE request.
The documentation site of the API you're working with should note which types of requests are supported for each particular action. In our case, the type of request required for each particular action is noted via a color coded button in its documentation, like the screenshot below.
For instance, if we want to modify donation records, with the v2 Neon CRM API, that's a PATCH request as the Neon CRM v2 documentation site says:
On the other hand, if we wanted to create a new donation (or batch of donations), using the v2 Neon CRM API, that's a POST request:
All of this is provided for you in the reference documentation you downloaded and imported into Postman for v2 of the Neon CRM API, so now that we've got the basics out of the way, we're ready to test our environment settings.
Testing your Environment
The simplest way to test your environment setup is to run a GET request to pull an account from the CRM you're working with.
Open the "accounts" folder under all of the Neon CRM API v2 requests you imported from the developer documentation page, open up the {id} section, which denotes actions you can perform by simply providing an account ID, and highlight "GET Gets an account".
This will open up that request in a tab on the right side of Postman, as mentioned before, like opening a new browser tab.
{{baseUrl}} will fill in the base URL of the API from our environment settings, using the exact same formatting as a Campaign Email token in the CRM. As you can see on the end of the request, it wants an account id, so we could simply replace ":id" with a known account ID in the target CRM we're working with.
Lastly, we need to change the "Authorization" parameters for this request to match the variables we put in earlier for the Environment that holds those values, and the setting in the collection which generates basic authentication. This is just a couple of clicks to set a request to "basic auth" and "inherit auth from parent", like so:
In my case, the Test account I created in this customer in question's CRM during a configuration meeting is still present, so we could fetch that account by ID from the Neon CRM v2 API like so:
After you fill in the account ID on the address line of the request and hit the blue "Send" button, you should see the response of your request in the lower status window which was previously blank.
NOTE: when you close the "tab" that the request you sent is in, Postman will ask if you if you want to save the changes. Unless you only ever want to get account ID #6 for time immemorial, forsaking all other account IDs, you probably want to say "no" and leave the reference request(s) you downloaded alone. We'll go over how to make a new collection of "customized" requests later in this guide.
If you're familiar with data from the CRM, all of the items you get in response should be fairly self explanatory in the above screenshot, and you can probably see where this guide is going! If we can GET stuff like this from the CRM, we can logically also put things back into the CRM using the same methods and format.
On the "status" line atop the status window in the screenshot above, you'll also see "200 OK".
These number codes are standard across the internet from web servers (including API servers), and in our case can be used to determine whether what we tried to do was successful or not. If you want to read all about HTTP status codes the Mozilla web developer documentation has plenty, but for our purposes the important things are:
- 200-299 status numbers mean "success"
-
400-499 status numbers mean "failure", and in particular among those:
- 400 means "bad request" (malformed, formatting errors, etc.)
- 403 means "unauthorized" (something wrong with your username or API key)
- 404 means "not found" (the thing you're looking for doesn't exist... in the above example, trying to GET an account ID which didn't exist in the target CRM would return a 404)
Building an API Request
Now that we have a working environment set up to test API requests, let's build a working example. Let's say we need to batch enter in-kind donations based on data that a donor submits in a form, as an example. For the sake of neatness, it's a good idea to make a new collection to work from, so you can do so by clicking the "New Collection" button in Postman, like so:
Name your new collection "Neon CRM In-Kind submission" like so:
Next, since an In-Kind donation is a type of donation, we should copy over the reference request from the CRM API Reference that we imported previously.
Expand the CRM API Reference, expand the donation section, and find the "create a donation" POST request, then make a copy of it by right clicking on it, like so:
After making a copy of the reference request for this example, you can drag your copy down to the bottom of the left hand pane of Postman and drop it in your new collection, like dragging a bookmark around in your web browser's bookmark editing menu:
Now that we have a copy of the reference, we can edit it to do what we want it to do.
Generally speaking, the reference CRM API requests are over-full in terms of options. The reference lists every possible value you can write to the CRM database with a particular request, and it's implied that you will edit it to remove things you don't need to write, leaving only the things you do want to write.
In the example of our In-Kind donation, we want to write the following fields...
Required fields:
- "accountId"
- "date"
- "amount"
- "payments" (more on this as we go)
Optional fields we also may want to include:
- "sendAcknowledgeEmail"
- "campaign"
- "fund"
- "purpose"
As suggested above the top four fields must be filled in for the submission to succeed, they are required. Other fields may be included, if necessary.
Since our reference requests includes far more than we need, we can start by editing it down to only show what we need to send.
Remember above the suggestion to download a programming file editor? Postman also contains one, and here's a good example of why we need one.
APIs like the CRM use a structured format called JSON (javascript object notation) to reference data fields and values. Typos are not allowed, because the data is structured for a computer to read, any error, even just a missing comma, will cause the CRM API to do nothing and return an error to you. A programming editor like VS Code or the one inside of Postman will highlight these errors for you:
The red squiggly lines under those commas? That means something isn't right here, it's telling you where the error is. If you make a mistake at any point and see red squiggly lines, you can ctrl+Z on your keyboard to undo the last change you made.
At this point, edit your working copy of the create a donation request down to the fields we need, like so:
It's worth noting here that Javascript and JSON have some control characters which imply certain things.
- curly brackets {...} indicate an object, a single item which may have more than one property value
- square brackets [...] indicate a list, an object that may have more than one item in it
- for each item in a list or object, each successive row of field + value should end in a comma, except the last row, which should not have a comma (as if you were typing them in a plain English language paragraph, for example)
It's also important to understand here that the default values from the reference request for each field indicate the type of data that the CRM API expects.
- "<string>" means plain text, quoted with double quotes on each end
- "<dateTime>" means a javascript date time stamp, YYYY-MM-DDThh:mm:ss.msZ, also double quoted
- "<boolean>" means true or false, without any quotes
- "<number>" means digits or a decimal, without any quotes
For the date format:
- YYYY = year (four digits)
- MM = month (two digits)
- DD = day (two digits)
- T = T (just like it reads)
- hh = hour (two digits, 'military time')
- mm = minutes (two digits)
- ss = seconds (two digits)
- Z = time zone (Z is for Zulu time, the default computer time, in Greenwich, UK, can also be an offset from Z, ex: -06:00 instead of the Z for CST... 2026-08-25T10:45:00-06:00, to get your Zulu time offset you can simply google "Zulu to CST time" and it will tell you the value)
So a complete request with the data filled in for the above in-kind donation example for a timezone of CST (-06:00 from Zulu time) would look like this:
Note that the campaign, fund, and purpose are referenced by their IDs. This is universal throughout the CRM API. If a thing has an ID, you need to reference it by that ID. This is by design, for example you may want to rename a campaign to a different name in the CRM, but if you had automations referencing that campaign by name the automation would break. If you reference it by its ID, renaming in the admin side of the CRM is harmless, and the automation would not break.
The CRM has many "helper" endpoints that return items alongside their IDs to facilitate this translating of names to IDs.
For example:
https://developer.neoncrm.com/api-v2/#/Properties/listFundsUsingGET returns all funds in your CRM, along with their IDs. The same endpoints exist for campaigns, purposes, tender types, sources, custom fields, etc.
These "property" endpoints do not require any configuration, they are just GET requests that return all values, so you simply change the authorization portion of the request to find your username and API key and run them.
It's also worth noting that JSON can be converted to CSV, so to process a batch of these, it would be helpful to convert the return of the property endpoints for campaigns, funds, and purposes to a CSV so that we can simply XLOOKUP in a spreadsheet to fill them in a spreadsheet batch.
Postman can run a batch of requests from a CSV file, so this ties all of our example here together nicely. More on that as we go.
There are extensions for VS Code that can do this for you, or you can simply use any number of websites that will take JSON and output CSV, like this one (don't put sensitive data in these sites, but if you just need to convert campaign names to IDs...):
https://convertcsv.com/json-to-csv.htm
Copy JSON in the top box and you'll get a CSV output in the bottom that you can download, like so:
After running our above test with real values, we should get a success message in Postman and we can check the CRM to see that the in-kind donation was created, like so:
If your API request test did not work, the status window at the bottom of the request in Postman will show an error, like this, the underlined portions tell you that the request failed (status: 400, corresponding to the codes explained above), along with the reason why (my purpose ID is not valid):
It should be noted that no one gets these correct out of the box. Any sort of automation or programming is a process of trial and error. Rather than spending a lot of time reading and re-reading what you have, it's much more efficient to simply submit what you have, get the error, and start eliminating the errors until they go away and the test succeeds.
Failure isn't a personal judgment, the computer tells you what's wrong. Reporting a failure is supposed to be helpful in debugging, so just submit your test over and over, reading the errors and fixing them as you go.
So all of the above gets us ready to run one request, but surely we don't want to go to all of this trouble just to do one thing. As mentioned above, Postman can do these things in batches from a spreadsheet.
That brings us to: the runner.
The Runner
As the environment can hold variables which can be called in {{curlyBracketNotation}}, so can Postman loop over a CSV spreadsheet, using the column headers as variables, and run a single request hundreds (or thousands) of times for you.
So for the values in our in-kind request, we should fill in some variable names for column headers in a spreadsheet, like so:
Then fill in some dummy values, like so:
Next we need to convert our date/time format to what the API wants here, this a simple spreadsheet value formatting exercise. Highlight the date/time column, and make a format to convert the values to, like so:
After doing the above custom date / time format once, Google sheets remember your custom date / time formats for you, like so, making these handy to re-use in the future:
Next we have a simple exercise of transcribing the column headers we need to fill values for into Postman in place of the test values, and save the request with the variables in place, like so:
Remember the point above about how you can convert JSON to CSV? This makes filling in those campaign, fund and purpose IDs very easy!
If you run the requests to get these properties and their values from the CRM reference requests for them, you can just copy and paste the returned values into a convert CSV tool and then download the spreadsheets and import them into the Google sheet we're working from, and then you're just an XLOOKUP away from filling them all with a spreadsheet formula, like so:
Lastly, remember how we set our reference requests to "inherit auth from parent?" For the username and API key settings? You'll need to do the same for your reference request, or set it to use your environment variables, like so:
Now we have a spreadsheet batch ready to go, and we're ready to open the runner and run the batch.
Click the runner at the top left of the Postman window:
Next, pick the collection you want to run (the Runner runs whole collections by design, be sure to deselect the requests we don't want to run and only select the ones we do, if there are multiple requests in a collection!)
Next, select the environment from the dropdown that has your username and API key stored in it:
And next, select your CSV that you downloaded from the Google sheet, or saved from Excel:
Note that the "Iterations" number is read from the CSV, and is Postman's way of saying how many requests will be sent. If you want to run a test row again, you can adjust this number to "1" and it will only run the first row of the CSV spreadsheet, again this is helpful for testing purposes.
Lastly, the Neon CRM API like most others has a flood limit. You cannot flood it with thousands of requests all at once, so you need to put a delay in your request Runner loop to stop Postman from doing so.
The value in the "Delay" box is in milliseconds, and 150 is fine for a setting here. That will make Postman separate your requests by 150 milliseconds each.
So our complete, ready to go batch-run would look like this:
Then, all you have to do is scroll down to the blue button and click it to run your batch, like so:
From here, Postman will run your batch from the spreadsheet, and output log rows that show you whether each row in the batch succeeded or failed, by the return code (200 is good, 400+ is bad), like so:
Oh no, all of our requests failed (if you have a lot in a batch, there is a "stop" button as well which you can use to stop what it's doing)!
Which brings us to: debugging in the runner.
Debugging Requests
If something goes wrong (it will, no one gets these right on the first try), debugging is pretty easy.
In the runner console, you can open up the log of a runner action and look at the body of the request response from the server, and it will tell you what was wrong with your request.
Lets take a look at what we got from the first run of our in-kind batch. Expand one of the rows in the log, then expand the request body section of the row, like so:
The {{Tender Type}} column from the spreadsheet isn't finding its value, because we forgot to add it to the spreadsheet columns. This is a simple fix, adjust the spreadsheet and re-download it.
Then just re-download / re-save the spreadsheet and try again. Remember how to get Tender Type IDs? There's a "get tender types" helper request under the payments section! Simply run it and find the in-kind tender type ID and you can fill it manually for all the rows. If you have multiple payment types, you'll have to re-adjust your spreadsheet structure, of course.
Now try again:
All rows are "200 OK" that means they all worked, and we should see them in the CRM. If we pull up our test account and filter its donations to in-kind for the tender type, we should see our created donations, and there they are:
Where do I go from here?
If you've made it this far, you've built a rather complex API request from scratch.
Syntax matters a lot, as we've seen... You have to reproduce the sample body from the documentation / reference request precisely. You have to take out bits you're not using. You have to double check keys and values to make sure you're only sending what you want to send. You get the idea.
As mentioned previously, it's a good idea to save the modified versions in separate collections. You might need to refer back to them... for reference... hence the terminology here.
Presumably, you will want to use the API with an integration tool like Zapier, make.com or n8n.io to further automate what you're trying to accomplish, and have data from webhooks populate data in subsequent API requests to have the automation tool completely handle tasks on its own, like a workflow does.
And now that you have a guide and reference for how to build out these requests from scratch, there's nothing stopping you from doing (almost) anything you want to do in terms of CRM automations. The CRM API can do almost anything to your data, you just have to wire it up, request-by-request, and once you've tested the chain of actions it's just a matter of copying and pasting the JSON from each request body from Postman over to your automation tool, and sending a webhook by creating something manually in the CRM to test the whole chain of actions in your automation.
Bonus: with some Javascript knowledge you can build complex requests that talk to each other!
For example, I built this one, attached to this guide, to patch company contacts in place.
Adding custom Javascript code to the "test" and "pretest" events in Postman is how this works. As the name suggests, pre-test scripts run before a request is sent, and test scripts run after a request is sent. So in the example attached to the bottom of this guide, using a spreadsheet full of company names with their primary contacts on the same row, Postman will fetch all of a company account's contacts using the GET company account contacts request, and in the "test" script that runs after each company contact request is fetched, Postman will find the primary contact in that company, and then send a secondary request to update the contact record on the company for the primary membership contact with new address, phone, email, and other such data.
Caveats and Considerations
It should go without saying that API requests can't be un-done. Test, test, test. Verify, verify, verify.
If you start 10,000 rows of something that's inherently wrong in some way in the Runner, you're going to have a not-so-fun time deleting all of those donations and re-importing them.
Also, generally speaking APIs don't handle null / blank values very well. So in this example if we included the payment note field, for example, requests would fail where the payment note was blank. We'd have to separate those into another sheet and only send complete requests where every key / value had data in it.
Here's the above concept graphically in the spreadsheet in question, presuming our intent in this guide of running payment patching requests to add payment notes and tender types from the client, if we ran the whole CSV as-is:
On the blank payment note lines the whole request will fail, not just the payment note portion of the request. It's all or nothing, API requests to the CRM are "atomic" meaning that they either completely succeed, or completely fail.
In short, the API is not forgiving like the CRM's Import Manager spreadsheet importer is, it will do precisely what you tell it to do (only), and if you get something wrong it'll probably just do nothing, and give you an error.
That's why Postman exists, it's a test tool. Build, test, verify, then automate after you've done those three first.