DEV Community

Cover image for AI Writes Your API Code. Who Tests It?
Preecha
Preecha

Posted on

AI Writes Your API Code. Who Tests It?

How to Test AI-Generated API Integrations Before Production

TL;DR

AI coding assistants such as Claude, ChatGPT, and GitHub Copilot can generate API integration code in seconds. Anthropic’s Code Review tool can analyze that code for logic and security issues. However, neither code generation nor code review proves that an integration works against a real API. Authentication failures, incorrect endpoints, rate limits, and response mismatches can still break production deployments. Apidog closes this gap by letting you execute AI-generated API requests, validate responses, and automate API tests before deployment.

Try Apidog today

The AI Code Generation Boom

AI coding assistants have changed how developers build integrations. A prompt such as “integrate the Stripe payment API” can produce a complete client in seconds. GitHub Copilot can autocomplete entire functions, while ChatGPT and Claude can generate API clients from natural-language requirements.

The result is faster implementation:

  • AI coding tools are used daily by a large portion of developers.
  • Developers can generate multiple API integrations each week.
  • Code generation is significantly faster than writing clients manually.
  • A growing share of new integration code is AI-generated.

This speed is useful, but generated code still needs to be validated against the real service.

Anthropic’s Code Review tool addresses part of the problem. Its multi-agent review process analyzes AI-generated code for logic errors, security issues, and code-quality problems.

Image

Code review does not verify that an API integration works at runtime.

A reviewed integration can still fail because of:

  • Incorrect authentication headers
  • Outdated endpoint URLs
  • Invalid or expired credentials
  • Rate limits
  • Network timeouts
  • Differences between documented and actual response formats
  • Missing or unexpected response fields

Code review checks whether the implementation makes sense. API testing checks whether it works.

With Apidog, you can reproduce the requests generated by an AI assistant, execute them against an API, inspect the response, and add assertions before the integration reaches production.

The Testing Gap

AI assistants are trained on large collections of code and documentation. They know common API patterns, authentication flows, and data structures. As a result, they often produce code that is syntactically valid and logically plausible.

That does not mean the code matches your environment or the provider’s current API.

Neither an AI coding assistant nor a static code review can reliably determine:

  • Whether your API key is valid
  • Whether an endpoint changed recently
  • Whether production returns the same data as the documentation
  • Whether your request volume exceeds a quota
  • Whether the response matches the types your code expects
  • Whether the API is currently available

The only way to answer those questions is to test the integration.

Example 1: Stripe Payment Intents

Suppose you ask an AI assistant to create a Stripe PaymentIntent for $50:

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

async function createPayment() {
  const paymentIntent = await stripe.paymentIntents.create({
    amount: 5000,
    currency: 'usd',
    payment_method_types: ['card'],
  });

  return paymentIntent.client_secret;
}
Enter fullscreen mode Exit fullscreen mode

A code review may confirm that:

  • The amount is represented in cents
  • The API key is loaded from an environment variable
  • The Stripe SDK syntax is valid
  • The function returns the client secret

The integration can still fail in production if:

  • Production uses a different Stripe account
  • The key does not have the required permissions
  • European customers require eur instead of usd
  • The account reaches a rate limit
  • The payment webhook is not configured

The code can be logically correct while the integration is operationally incorrect.

Example 2: Weather API Rate Limits

An AI assistant may generate a correct request to the OpenWeatherMap API. The request works locally, so the integration passes a basic test.

After deployment, 10,000 users send requests through the free-tier account. The account’s request limit is exceeded, and the application begins returning errors.

The generated code did not know your expected traffic volume. Code review did not exercise the quota. A request runner, load test, or mock response for rate limiting would have exposed the missing behavior.

Example 3: OAuth Configuration

An AI assistant can generate a structurally correct OAuth2 flow:

  • Authorization URL
  • Token exchange
  • Token storage
  • Refresh-token handling

The integration can still fail because:

  • The redirect URL points to localhost
  • The token refresh endpoint is outdated
  • The requested scopes do not match the application configuration
  • The provider has changed its authentication method

These are configuration and runtime problems. They cannot be detected by reviewing the control flow alone.

Why Manual Testing Does Not Scale

The traditional workflow is:

  1. Generate or write the code.
  2. Review the implementation.
  3. Open a REST client.
  4. Build a request manually.
  5. Inspect the response.
  6. Test error cases.
  7. Repeat for every integration.

This approach may work for a few integrations per week. It becomes expensive when AI generates 15–20 integrations per week.

A typical workflow might take:

  • AI code generation: about 30 seconds
  • Code review: about 2 minutes
  • Manual API testing: 15–30 minutes
  • 20 integrations per week: 5–10 hours of testing

Teams usually respond in one of three ways:

  1. Skip testing

    Assume the generated and reviewed code is correct.

  2. Spot-check a few integrations

    Test only two or three examples and hope the remaining integrations behave similarly.

  3. Test everything manually

    Spend a significant portion of the week validating requests and responses.

None of these options preserves the speed advantage of AI-assisted development. The missing step is automated API testing.

A practical workflow is:

AI generates the integration
        ↓
Code review checks logic and security
        ↓
Apidog executes and validates API requests
        ↓
CI/CD runs the tests on every change
        ↓
Deploy only after the tests pass
Enter fullscreen mode Exit fullscreen mode

The Cost of Untested AI Code

The original analysis referenced a 67% first-deployment failure rate for AI-generated API integrations. The reported failure categories were:

  • 28% authentication errors
  • 22% endpoint errors
  • 18% data-format errors
  • 15% rate-limiting issues
  • 17% other issues, including timeouts, network errors, and CORS problems

Regardless of the exact distribution, each failure creates additional work.

Developer time

If debugging a failed integration takes 45 minutes, even a small number of runtime failures can consume several hours each week.

Developers must investigate:

  • The generated request
  • Environment variables
  • Authentication permissions
  • API versions
  • Response bodies
  • Retry and timeout behavior
  • Differences between local and production configuration

Production incidents

Untested integrations can cause:

  • Failed payment processing
  • Broken authentication
  • Missing dashboard data
  • Failed background jobs
  • Increased support requests

User impact

Users may see:

  • Error messages instead of completed actions
  • Slow pages caused by timeouts
  • Missing or stale data
  • Failed uploads or transactions

The result is an uncomfortable trade-off: AI makes code generation faster, but untested integrations can make delivery slower.

How to Test AI-Generated API Code with Apidog

The goal is not to stop using AI. The goal is to validate its output quickly and repeatably.

Step 1: Generate the integration

Start with a focused prompt. For example:

Write a Node.js function that fetches a GitHub user's profile.
Use the GitHub REST API, include the required headers,
and throw an error for non-2xx responses.
Enter fullscreen mode Exit fullscreen mode

A generated implementation might look like this:

async function fetchGitHubUser(username) {
  const response = await fetch(
    `https://api.github.com/users/${username}`,
    {
      headers: {
        Accept: 'application/vnd.github.v3+json',
        'User-Agent': 'MyApp',
      },
    }
  );

  if (!response.ok) {
    throw new Error(`GitHub API error: ${response.status}`);
  }

  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Before using the function in production, reproduce its request in Apidog.

Step 2: Create the request in Apidog

Create a request with:

  • Method: GET
  • URL: https://api.github.com/users/{{username}}
  • Headers:
    • Accept: application/vnd.github.v3+json
    • User-Agent: MyApp
  • Environment variable: username

Using variables keeps the request reusable across environments and test cases.

The request view lets you inspect the method, URL, headers, parameters, and body that will be sent.

Step 3: Execute the request

Run the request and inspect:

  • HTTP status code
  • Request headers
  • Query parameters
  • Request body
  • Response headers
  • Response body
  • Response time
  • Error details

This immediately verifies the assumptions in the generated function:

  • Is the endpoint correct?
  • Are the headers accepted?
  • Does authentication work?
  • Does the response contain the fields the code expects?
  • What happens when the API returns an error?

Step 4: Add assertions

A request that returns 200 OK is not necessarily correct. Add assertions for the response contract.

For example:

pm.test('Status is 200', () => {
  pm.response.to.have.status(200);
});

pm.test('User has required fields', () => {
  const user = pm.response.json();

  pm.expect(user).to.have.property('login');
  pm.expect(user).to.have.property('id');
  pm.expect(user).to.have.property('avatar_url');
});

pm.test('ID is a number', () => {
  const user = pm.response.json();

  pm.expect(user.id).to.be.a('number');
});
Enter fullscreen mode Exit fullscreen mode

These tests verify both the status code and the response structure. Run them whenever the request is executed, locally or in CI/CD.

Step 5: Test failure cases

AI-generated code often focuses on the happy path. Add cases that exercise failure handling.

Invalid username

Request:

https://api.github.com/users/this-user-does-not-exist-12345
Enter fullscreen mode Exit fullscreen mode

Verify that:

  • The API returns the expected 404 response.
  • The application converts the response into a useful error.
  • No code attempts to read fields from a missing user object.

Rate limiting

Send enough requests to exercise the provider’s limit, where permitted by the API terms.

Verify that:

  • The response status is handled.
  • Rate-limit headers are read correctly.
  • Retry or backoff behavior exists where appropriate.
  • The application does not retry indefinitely.

Network timeout

Configure a deliberately short timeout in a test environment.

Verify that:

  • The request fails with a timeout error.
  • The application returns a controlled error.
  • Background jobs can retry safely.

Malformed responses

Use a mock response with missing or incorrectly typed fields.

Verify that:

  • Response validation fails clearly.
  • The application does not crash unexpectedly.
  • Invalid data is not persisted or displayed as valid.

Apidog mock servers can simulate these responses without repeatedly calling the external API.

Automated API Testing Workflows

Manual exploration is useful during development. Automated tests are what prevent regressions.

Workflow 1: Test-driven AI development

Define the API contract before asking AI to generate the implementation:

  1. Create the request in Apidog.
  2. Define required headers, parameters, and body fields.
  3. Add status-code and response assertions.
  4. Document expected error behavior.
  5. Give the contract and API documentation to the AI assistant.
  6. Generate the implementation.
  7. Run the tests against the implementation and API.

This approach changes the role of AI. Instead of generating code first and testing later, you define the expected behavior and generate code that must satisfy it.

Workflow 2: Run tests in CI/CD

Store your collection and environment configuration with the project, then execute the tests in your CI pipeline.

Example GitHub Actions workflow:

# .github/workflows/api-tests.yml
name: API Tests

on:
  push:
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Run Apidog tests
        run: |
          npm install -g apidog-cli
          apidog run collection.json --environment prod
Enter fullscreen mode Exit fullscreen mode

A production setup should load secrets from the CI provider rather than committing them to the repository.

Run the collection on every pull request and commit. If an AI-generated change breaks authentication, response validation, or error handling, the pipeline can fail before the change is merged.

Workflow 3: Continuous monitoring

Schedule API checks at regular intervals to detect failures outside the deployment workflow.

Useful checks include:

  • Endpoint availability
  • Authentication validity
  • Response-time thresholds
  • Expected status codes
  • Required response fields
  • Rate-limit behavior

Monitoring can detect provider-side changes, downtime, endpoint migrations, and quota problems before users report them.

Best Practices

1. Test generated code immediately

Run the generated request while the implementation context is still fresh. Immediate feedback makes it easier to determine whether the problem is in the prompt, generated code, credentials, or API configuration.

2. Use environment variables for secrets

Do not hardcode keys in generated code:

const API_KEY = 'sk_test_12345'; // Avoid this
Enter fullscreen mode Exit fullscreen mode

Use an environment variable instead:

const API_KEY = process.env.STRIPE_API_KEY;
Enter fullscreen mode Exit fullscreen mode

Use separate values for development, staging, and production. Keep secrets out of source control and shared collections.

3. Validate the complete response contract

Do not stop at status-code checks. Assert:

  • Required fields
  • Data types
  • Nested object structure
  • Error response shape
  • Pagination metadata
  • Headers used by retry or rate-limit logic

A successful response with an incompatible schema can still break the application.

4. Version-control your tests

Store collections and test definitions with the application:

git add apidog-collection.json
git commit -m "Add tests for GitHub integration"
Enter fullscreen mode Exit fullscreen mode

Update the tests when:

  • AI generates a new integration
  • The provider changes its API
  • The response contract changes
  • Authentication requirements change

Versioned tests provide a shared source of truth for developers, QA, and CI/CD.

5. Mock external APIs during development

Use mock servers when you need predictable responses or want to test failure paths.

Mocking helps you:

  • Avoid network latency
  • Simulate timeouts and server errors
  • Test malformed responses
  • Avoid external rate limits
  • Reduce unnecessary API usage

Use real API checks as well when validating credentials, provider behavior, and deployment configuration.

6. Configure alerts

Set thresholds for conditions such as:

  • Response time above two seconds
  • Error rate above one percent
  • Unexpected status codes
  • Authentication failures
  • Missing response fields

The exact thresholds should match your application’s requirements.

7. Review the generated code as well as the request

API tests do not replace code review. AI-generated code can still contain:

  • Deprecated API versions
  • Missing error handling
  • Hardcoded values
  • Inefficient logic
  • Security vulnerabilities

Use both layers:

Code review → Is the implementation safe and logically correct?
API testing  → Does the integration work with the actual contract?
Enter fullscreen mode Exit fullscreen mode

Conclusion

AI coding assistants can generate API integrations much faster than manual development. Code review tools can identify logic and security problems in that generated code. Neither step proves that the integration works against a real API.

Runtime failures still come from:

  • Incorrect authentication
  • Outdated endpoints
  • Rate limits
  • Timeouts
  • Configuration mismatches
  • Unexpected response formats

Apidog adds the missing API-testing layer:

  1. Generate the integration with AI.
  2. Review the implementation.
  3. Reproduce the request in Apidog.
  4. Add response and error assertions.
  5. Run the collection in CI/CD.
  6. Monitor important endpoints continuously.

Code review checks logic. API testing checks reality. Together, they let you keep the speed of AI-assisted development without relying on untested integrations.

FAQ

Can AI tools test their own code?

AI tools can generate test code, but generating tests is not the same as executing requests against the real API. Runtime testing requires credentials, network access, and response validation.

How long does it take to test AI-generated API code?

For a simple integration, importing the request, executing it, and checking the result can take about 30–60 seconds. Adding assertions and edge cases takes longer but creates reusable coverage.

What if the AI-generated code is wrong?

Use the request and response details to identify the failure:

  • Wrong endpoint
  • Invalid authentication
  • Incorrect parameters
  • Unexpected response structure
  • Missing error handling

Fix the implementation or configuration, then run the request again.

Do I need to write every test manually?

You can start with basic generated or request-level tests, then add custom assertions for important business rules, response fields, and failure conditions.

Can Apidog test GraphQL APIs?

Apidog supports REST, GraphQL, WebSocket, and gRPC APIs. The same workflow applies: create the request, execute it, validate the response, and automate the collection.

How should I handle API keys and secrets?

Store credentials in environment variables or your CI/CD secret manager. Do not hardcode them in AI-generated code or commit them to source control. Use separate credentials for development, staging, and production.

How do I test rate limiting?

Use a test runner to send repeated requests where allowed by the provider’s terms, then verify the status code, rate-limit headers, and retry behavior. You can also use a mock server to simulate rate-limit responses without calling the real API.

Can I run AI-generated API tests in CI/CD?

Yes. Use the Apidog CLI in systems such as GitHub Actions, GitLab CI, Jenkins, or another CI/CD platform. Run the collection on pull requests and commits so integration failures are detected before deployment.

Top comments (0)