Forum Discussion

alimak's avatar
alimak
Copper Contributor
Aug 21, 2025

joinUrl is null when fetching via /chats/

Hi we have a production app for Teams that has broken as a result of a seemingly random api change that we can't find any documentation for in the api change log or anywhere for that matter.

We are sending the following request via our front end app:

https://graph.microsoft.com/v1.0/chats/19:meeting_MDc0NmQ4OWYtNTNiOC00NjY2LWIzYWItZGQ3ZTQyMWFjNzk2@thread.v2

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#chats/$entity",
    "id": "19:meeting_MDc0NmQ4OWYtNTNiOC00NjY2LWIzYWItZGQ3ZTQyMWFjNzk2@thread.v2",
    "topic": "Besprechung mit <organiser_name>",
    "createdDateTime": "2025-08-21T10:41:11Z",
    "lastUpdatedDateTime": "2025-08-21T12:49:30.002Z",
    "chatType": "meeting",
    "webUrl": "https://teams.microsoft.com/l/chat/19%3Ameeting_MDc0NmQ4OWYtNTNiOC00NjY2LWIzYWItZGQ3ZTQyMWFjNzk2%40thread.v2/0?tenantId=<tenant_id>",
    "tenantId": "<tenant_id>",
    "isHiddenForAllMembers": false,
    "viewpoint": {
        "isHidden": false,
        "lastMessageReadDateTime": "2025-08-21T12:59:24.376Z"
    },
    "onlineMeetingInfo": {
        "calendarEventId": null,
        "joinWebUrl": null,
        "organizer": {
            "id": null,
            "displayName": null,
            "userIdentityType": "aadUser"
        }
    }
}

 

In this request we would parse `onlineMeetingInfo` for the joinWebUrl however we now get `null`

We've tried using the webUrl but this does not work since it doesn't contain the organisation Id which we later rely on.

Our flow is the following:

  • We make a graph api request to fetch the joinUrl
  • We send the joinWebUrl to our backend
  • That Url is passed to a Teams Bot we are hosting on Azure which parses the URL to send a bot join request to Microsoft.

However the new webUrl does not have the organiser Id and as a result the bot fails to join. We've verified by hardcoding the organiser Id

var meetingInfo = new OrganizerMeetingInfo
        {
            Organizer = new IdentitySet
            {
                User = new Identity { Id = <we_hard_coded_this> },
            },
        };
        meetingInfo.Organizer.User.SetTenantId(tenantId)

And we then use this as following:

var tenantId = (meetingInfo as OrganizerMeetingInfo)?.Organizer
    .GetPrimaryIdentity()
    .GetTenantId();

var mediaSession = this.CreateLocalMediaSession();

var joinParams = new JoinMeetingParameters(chatInfo, meetingInfo, mediaSession)
{
    TenantId = tenantId,
};

if (!string.IsNullOrWhiteSpace(callParams.DisplayName))
{
    // Teams client does not allow changing of ones own display name.
    // If display name is specified, we join as anonymous (guest) user
    // with the specified display name. This will put bot into lobby
    // unless lobby bypass is disabled.
    joinParams.GuestIdentity = new Identity
    {
        Id = Guid.NewGuid().ToString(),
        DisplayName = callParams.DisplayName
    };
}

if (!callParameters.TryAdd(chatInfo.GetMeetingId(), new()
{
    AccessToken = callParams.AccessToken,
    AccountId = callParams.AccountId,
    BackendUrl = callParams.BackendUrl,
    JoinUrl = callParams.JoinUrl,
    Protocol = callParams.Protocol,
    Origin = callParams.Origin,
    InviterParticipantId = callParams.InviterParticipantId,
    SubscriptionId = callParams.SubscriptionId,
}))
{
    logger.Warning("Parameters for call already exist.");
}

var statefulCall = await this.Client.Calls()
    .AddAsync(joinParams)
    .ConfigureAwait(false);

 

This is quite urgent as it's impacting our customers, could someone please have a look at provide us an update here?

 

Thank you.

2 Replies

  • Victor-RD's avatar
    Victor-RD
    Occasional Reader

    I have the same problem, suddenly joinWebUrl is null without any change in our side, this is impacting our app

     {
        "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#chats(onlineMeetingInfo)/$entity",
        "onlineMeetingInfo": {
          "calendarEventId": null,
          "joinWebUrl": null,
          "organizer": {
            "id": null,
            "displayName": null,
            "userIdentityType": "aadUser"
          }
        }
      }

     

  • pradejain's avatar
    pradejain
    Iron Contributor

    alimak​  Simplest solution with minimal changes.

    Keep your existing chat.onlineMeetingInfo call, but only replace the missing joinWebUrl lookup with a direct Graph onlineMeetings query using the joinMeetingId from that same object.

    Example:

    http

    GET /me/onlineMeetings?$filter=joinMeetingIdSettings/joinMeetingId eq '{chat.onlineMeetingInfo.joinMeetingId}'

    • This preserves your current flow and data structures.
    • You only add one small Graph call when joinWebUrl is null.
    • No need to refactor bot join logic or remove OrganizerMeetingInfo unless you rely on it.

    This way, you patch the break with the least disruption to your existing code.

Resources