Skip to main content
Solved

Error extracting app_user_id from webhook in Supabase – 400 “user_id not found”


Forum|alt.badge.img

Hi everyone! 

I'm just getting started with programming, and I'm currently trying to integrate RevenueCat with Supabase to control user access based on subscription status.
I created an Edge Function in Supabase that receives the webhook from RevenueCat and tries to extract the app_user_id from the payload to identify the user and update their data.

The issue is: even though I can see the app_user_id correctly in the request body, I still get a 400 error saying "user_id not found". 🥲
Since I'm new to all this, there's a good chance I'm missing something simple — I'd really appreciate any help or guidance!

 

serve(async (req) => {
  try {
    const body = await req.json();

    const entitlement = body.entitlements?.premium_access;
    const event = body.event;

    const userId =
      body.app_user_id ||
      body.subscriber_attributes?.user_id?.value ||
      body.customer ||
      body.aliases?.[0];

    if (!userId) {
      console.error("user_id not found");
      return new Response("user_id not found", { status: 400 });
    }

    // further logic...

  } catch (e) {
    console.error("Unexpected error", e);
    return new Response("Server error", { status: 500 });
  }
});

Best answer by chris_perriam

Hi ​@osmanolanna, I think your issue is due to the body variable being used instead of event when reading the app_user_id.

Here’s an updated code sample:

serve(async (req) => {
  const body = await req.json();   // full webhook payload
  const event = body.event;        // the event section you need

  const userId = event.app_user_id;
  if (!userId) return new Response('app_user_id not found', { status: 400 });

  const hasPremium = event.entitlement_ids?.includes('premium_access');

  // update Supabase row…

  return new Response('ok');       // 200 response prevents retries
});

Helpful tips:

  • entitlements isn’t present in the webhook event; use entitlement_ids
  • Ensure that you’re correctly handling the type of webhook event. For example, you’ll want to ensure that you don’t grant someone access due to receiving a CANCELLATION event
  • A 200 response will avoid RevenueCat retrying the same webhook event
View original
This post has been closed for comments

2 replies

chris_perriam
RevenueCat Staff
Forum|alt.badge.img+4
  • RevenueCat Staff
  • 62 replies
  • Answer
  • June 30, 2025

Hi ​@osmanolanna, I think your issue is due to the body variable being used instead of event when reading the app_user_id.

Here’s an updated code sample:

serve(async (req) => {
  const body = await req.json();   // full webhook payload
  const event = body.event;        // the event section you need

  const userId = event.app_user_id;
  if (!userId) return new Response('app_user_id not found', { status: 400 });

  const hasPremium = event.entitlement_ids?.includes('premium_access');

  // update Supabase row…

  return new Response('ok');       // 200 response prevents retries
});

Helpful tips:

  • entitlements isn’t present in the webhook event; use entitlement_ids
  • Ensure that you’re correctly handling the type of webhook event. For example, you’ll want to ensure that you don’t grant someone access due to receiving a CANCELLATION event
  • A 200 response will avoid RevenueCat retrying the same webhook event

Forum|alt.badge.img
  • Author
  • New Member
  • 1 reply
  • July 1, 2025

Hey Chris!!

It worked perfectly!
You're a lifesaver — thanks to you, my app is running flawlessly now 😅


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings