top of page

Gaining API Technical Know-How For A Tech PM Role

Writer: HarshalHarshal

Trial-And-Error Example From A Product Manager Learning APIs From Scratch

Working in API-first companies means working close to the code — even if you’re not the one shipping it.

I was a Staff Product Manager at Twilio in an API-first product team a few years ago. I didn’t just want to understand the product — I wanted to experience the developer journey firsthand. Our users were developers, so I aimed to feel their friction points directly by walking through the setup, integration, and testing flows. 

This was my form of empathy-driven onboarding for the PM.

Now, 4 years later, I revisited those notes to resume API design. Below are snippets from my trials with:

  • Twilio’s SMS API

  • Technical documentation and console

  • Postman and cURL

  • Migration to Python code.

I spent 1 hour and 21 minutes writing this. You need 5 minutes to read this.

Pushing different levers of Curl with Get, Post, and secure identifiers.
Pushing different levers of Curl with Get, Post, and secure identifiers.

Related:

Goal

My goal was to:

  • Learn how the API works by using it myself

  • Identify friction points that new or less technical users might encounter

I’ll directly jump to takeaways and keep rest of the API trials for bottom of the article.

Takeaways: A Few Years Ago

Using a developer-focused product like Twilio as a semi-technical PM required persistence a few years ago. I wasn’t writing new APIs or building full apps, but I did:

  • Run and modify API calls

  • Interpret responses

  • Investigate errors

  • Compare SDKs with raw REST usage

  • Test messaging services at different delivery rates

These hands-on experiments helped me:

  • Build comfort with APIs

  • Identify UX gaps in developer tools

  • Understand how non-developers onboard to API-first products

You don’t need to be a backend engineer to build this skill. But you need a structured approach to debugging, and the patience to keep going when the docs don’t explain everything.

This trial-and-error approach later shaped how I designed APIs from first principles. When I worked on simplifying APIs for marketing and emergency notifications, I drew directly from these frustrations. I pushed for:

  • Clearer error messages

  • Consistent resource paths

  • Better onboarding flows

API Design: What I Wish I Knew Earlier

Years later, after reading and working on multiple APIs, I’ve built a better mental model for what separates good API design from frustrating ones. These best practices stand out:

  • Use clear, resource-oriented paths. Good: /api/messages/{id} and Bad: /getMessageInfo

  • Surface helpful, actionable errors.  “Invalid phone number format” is better than “400 Bad Request.”

  • Stick to standard formats. JSON is table stakes. YAML or form-encoded data adds friction unless truly needed.

  • Document everything, but especially edge cases. A good dev experience doesn’t just explain the happy path — it prepares you for the weird stuff.

Likely Takeaway: Developer Experience In 2025

I haven’t repeated this Twilio experiment using AI, but I’ve tackled other coding projects recently — and it’s clear the developer experience has become way easier.  I could “Vibe code” API interfaces and iteratively fix errors using tools like ChatGPT or GitHub Copilot. These can now:

  • Explain unfamiliar cURL flags

  • Convert shell scripts to Python

  • Debug confusing error messages

  • Help with API authentication workflows

In my projects, I used AI to create shell, Python, SQL, Javascript, Excel, and GCP scripts from scratch — and to debug fine-tuning failures in ML pipelines. In many ways, AI has become a second brain for developer experience: quick to try things, fast to explain, and endlessly patient.

Onboarding: Account, Login, Trial Message

Twilio’s web interface made it easy to create an account, log in, and send a test SMS. After signing up, I navigated to the Messages section and used the visual UI to send a message. It worked.

Next, I wanted to go deeper and try the API.

Trying cURL

The documentation suggested using cURL commands to trigger the API. It seemed like a simple place to start — no IDE, no project setup, just terminal commands.

But I quickly ran into issues:

  • cURL didn’t work in the Windows command prompt

  • It also failed in IPython

  • Small errors were hard to debug, and retrying required guessing what to tweak

I needed a better tool.

Using Postman

Many developers recommend Postman, so I installed it. Signing up and creating a project was straightforward. I copied the cURL command from Twilio’s console into Postman — but I wasn’t sure where each part of the request belonged.

For example:

--data-urlencode 'To=+16692640602' \
--data-urlencode 'MessagingServiceSid=MGxxxxxx' \
--data-urlencode 'Body=test from msg svc 1' \
-u ACxxxxx:[AuthToken]``` 

At first, I manually pasted the command into the Postman request. It didn’t work. Then I discovered the Import feature, which parsed the command into fields. Even then, it wasn’t clear where Postman stored parameters like Body or To.

I eventually sent the message. But editing the request and checking delivery status felt slow and clunky. Postman worked better for one-off calls, not for experimenting or iterating.

Moving To Code

I switched to writing code. Since I had used Python before, I chose it again. Setting it up took time:

  • Installed Node.js (required for some samples)

  • Installed Python and pip

  • Installed the Twilio Python SDK with pip install twilio

Switching to code may sometimes not have the code samples.
Switching to code may sometimes not have the code samples.

After setup, I copied sample code from Twilio’s documentation:

from twilio.rest import Client
account_sid = "ACxxxxx"
auth_token = "your_auth_token"
client = Client(account_sid, auth_token)
message = client.messages.create(
   to="+15558671234",
   from_="+15017251234",
   body="Hello from Python!")
print(message.sid)

This worked — I received the SMS on my phone. But now I had new questions:

  • What else could I do with message?

  • What other fields were available?

Testing SMS using API.
Testing SMS using API.

Exploring Message Metadata

I wanted to compare messages sent via Messaging Services versus direct API calls. Specifically, I wanted to:

  • Add a timestamp to each message

  • Check how long it took to deliver

  • Understand delivery status

Script to put timestamps and compare.
Script to put timestamps and compare.

The Try It Out section of Twilio’s console offered limited insights. It wasn’t obvious how to fetch message status or delivery timestamps.

Eventually, I found the right endpoint in the (now deprecated) API Explorer. It returned detailed fields like:

"status": "delivered",
"date_created": "2021-02-21 12:36:44+00:00",
"date_sent": "2021-02-21 12:36:44+00:00",
"date_updated": "2021-02-21 12:36:49+00:00"

By comparing date_created, date_sent, and date_updated, I could estimate delivery time. If I queried the message too early, the status appeared as sent instead of delivered. That confirmed how status updates worked.

API Explorer in the console.
API Explorer in the console.

Discovering API Nuances

Even simple tasks had hidden complexities:

  • Sending a message with a timestamp in the body helped track delivery.

  • Checking message status required using client.messages(SID).fetch() — whereas I assumed get() would work.

  • Using Messaging Services meant dealing with rate limits, sender pools, and other constraints that weren’t clearly explained in one place.

I also disabled Sticky Sender to see if it improved delivery time. It did — slightly.

Advanced abstractions also provide advanced features.
Advanced abstractions also provide advanced features.

Other Explorations

I tested opt-in/opt-out flows by texting “STOP” and “START” from my phone. That worked smoothly.

Testing whatsapp messaging using API.
Testing whatsapp messaging using API.

I also experimented with Twilio’s Usage API to query charges. But I couldn’t figure out how to filter by date or calculate totals for a single day. The API structure felt unintuitive.

Reviewing usage in a dashboard. 
Reviewing usage in a dashboard.

Looking back, it's clear how much easier things have become with conversational AI in 2025.

Recently, I used AI to generate shell, Python, SQL, and GCP Cloud Shell scripts. I also used it to debug AI fine-tuning errors and set up GCP.

Related:


 
 
bottom of page