Skip to content
Insights · Engineering

Which invite did that repository send?

Name the invite that repository sent: the id, the invitee, and the permission. A different id can share a login. Another repository omits it.

Scroll
EngineeringOct 30, 202612 min readBy Salman Naqvi, Founder & CEO
Which invite did that repository send?

A client says the builder was invited, or says the person who left still has the repository. Tonight, three proofs, in a repository the agency or the client can open. Name the invite that repository sent: the invitation id, the invitee, and the permission. If the account was added without an invitation, write that, and do not invent an id to fill the hole. Show a different invitation whose id, or whose invitee, is not this one. Show another client's repository that does not list this invitation. If any of the three needs a dashboard you cannot open, you have not named the invite. You have a login and a guess.

This is one repository invitation. It is not the person a repository added. Which person did that repository add? is a login and a permission on someone who is already a collaborator. An invitation can be open while that person is not yet on the collaborator list, and a login on the list is not an invitation id. It is not the role an invite granted. Which role did that invite grant? is the permission string after the fact. A role name is not this invitation's id. It is not the site a repository published. Which site did that repo publish? is a pages address, a branch, and a certificate date. It is not the fee a charge kept. Which fee did that charge keep? is a fee id. It is not the file a store accepted. Which file did that store accept? is a file id. It is not the rule a scan named. Which rule did that scan name? is an alert number, a rule id, and a state. It is not the secret an alert named. Which secret did that alert name? is an alert number, a secret type, and a state. A pending invite is none of those.

None of what follows is a permission grant for this client, and none of it is legal advice. The fields below are the published examples of a repository invitation and of an organization invitation. The examples that share an id do not share a node id. The figures below that are a census of other people's accounts on the same host. A count of developers is not the invitation the repository sent tonight.

GitHub's repository-invitation example and the example returned when a new invitation is created print the same invitation, except one of them stores expired and the other does not. The id is 1. repository.id is 1296269. 1 is not 1296269. 1296269 minus 1 is 1296268. The page's example does not print 1296268. The invitation url is https://api.github.com/user/repository_invitations/1296269. 58 characters. The path ends in the repository id, not in the invitation id. html_url is https://github.com/octocat/Hello-World/invitations. 50 characters. 50 is not 58. That address is a list page. It does not end in 1. node_id on the single object and on the create example is MDEwOlJlcG9zaXRvcnkxMjk2MjY5. 28 characters. The repository's node_id is the same string. An invitation node id that copies the repository node id is not a second object, and it is not proof that the two ids are the same kind of id. permissions is write. 5 characters. created_at is 2016-06-13T14:52:50-05:00. The single object prints expired false. The create example omits expired. False is not the same fact as a missing field. invitee.login is octocat. inviter.login is octocat. Both ids are 1. Both node ids are MDQ6VXNlcjE=. 12 characters. 12 is not 28. The sample invites the owner, as the owner. A sample that invites someone to a repository they already own is not your client's invite (GitHub, repository invitation example).

The list example is the same story with a different node id, and the repository block still does not match a careful read. The list item's id is again 1. Its node_id is MDQ6VXNlcjE=. 12 characters, the user node id, not the 28-character repository node id that the single object stored on the invitation. 12 is not 28. Same invitation id, two published node ids. The url still ends in 1296269. permissions is still write. expired is omitted, as on the create example, and unlike the single object. repository.name is Hello-World. 11 characters. full_name is octocat/Hello-World. 19 characters. 11 is not 19. description is This your first repo! 21 characters. The sentence does not contain the word is. 21 is not 11. hooks_url is http://api.github.com/repos/octocat/Hello-World/hooks. 53 characters, and the scheme is http. The same path under https is 54 characters. 53 is not 54. git_url is git:github.com/octocat/Hello-World.git. 38 characters. It does not contain the two slashes the other git addresses on the same object use. private is false. The owner id is 1, the same integer as the invitation id, the invitee id, and the inviter id. Four fields, one integer, and the url that is supposed to name the invitation uses 1296269 instead. Do not paste 1296269 down as the invitation id because it is the only large integer in the url.

The add-collaborator endpoint is how that invitation gets created, and its words do not match the invitation object. A new invitation returns 201. Adding someone who is already a collaborator returns 204. 201 is not 204. 204 has an empty body. An empty body is not id 1. The permission parameter on that request defaults to push. 4 characters. push is not write. 4 is not 5. The rendered invitation docs list the stored permissions as read, write, admin, triage, triage_plus, and maintain. The update-invitation body on the same docs lists read, write, maintain, triage, and admin. triage_plus is 11 characters. It is in the schema enum and not in that update sentence. push is the create default and is in neither list. The docs also name pull as a permission you can set on the add call. pull is 4 characters, the same length as push, and not the same word. You are limited to sending 50 invitations to a repository per 24 hour period, with no limit when you are inviting organization members to an organization repository. 50 is not 24. The list endpoint's default page size is 30, and the maximum is 100. 50 is not 30, and 50 is not 100. 30 is not 100. Enterprise managed users are not sent an invitation by that endpoint. A missing invitation, for that kind of account, is the documented behavior, not a lost email. Do not invent id 1 to fill it (GitHub, REST API endpoints for collaborators, and REST API endpoints for repository invitations).

The organization invitation example is a different object that reuses the integer. The id is 1 again. login is monalisa. 8 characters. email is octocat@github.com. 18 characters. The local part of the email is octocat, not monalisa. 8 is not 18, and the login is not the mailbox. role is direct_member. 13 characters. created_at is 2016-11-30T06:46:10-08:00. The repository example was 2016-06-13T14:52:50-05:00. The offset is -08:00 on the organization example and -05:00 on the repository example. The gap is 14,669,600 seconds: 169 days, 18 hours, 53 minutes, and 20 seconds. The example does not print that gap. inviter.login is other_user. inviter.id is 1, the same integer as octocat's id on the repository example. team_count is 2. The teams url is under organizations/2/invitations/1. The organization id in the url is 2. The invitation id in the url is 1. 2 is not 1. On the repository example, the url used the repository id instead of the invitation id. On this example, the url uses the invitation id and a different organization id. node_id is MDQ6VXNlcjE=. 12 characters, the same string as the repository list item's node id, and the same string as the user. invitation_source is member. The list form prints failed_at and failed_reason as empty strings. The single form omits them. An empty string is not a missing field, and neither is an invitation to octocat/Hello-World. A team count of 2 is not a permission of write (GitHub, repository invitation example).

The counts people quote when they want a GitHub figure did not open this invitation. GitHub's Octoverse report for 2024 says developers made more than 5.2 billion contributions to more than 518 million projects. 5.2 billion divided by 518 million is 10.039 contributions per project. The post does not print 10.039. It also says that in early 2023 the host reached 100 million developers. 518 million divided by 100 million is 5.18. The post does not print 5.18, and the 100 million figure is an earlier year than the 518 million figure. Contributions to generative AI projects rose 59 percent, and the number of such projects rose 98 percent. 98 minus 59 is 39. The post does not print 39. 59 is not 98. Jupyter Notebook usage rose 92 percent. 92 is not 98, and 92 is not 59. The GitHub Education program has had more than 7 million verified participants. 7 is not 100. A doubling, which the same post prints as 100 percent year-over-year for one Copilot access program, is not a 59 percent rise. None of these is invitation id 1, and none of them is permission write (GitHub, Octoverse 2024).

The same post's country tables do not add to a population you can hand a client. The printed floors for five Latin American communities are Brazil more than 5.4 million at 27 percent, Mexico more than 1.9 million at 21 percent, Colombia more than 1 million at 25 percent, Argentina more than 1.1 million at 22 percent, and Peru more than 583 thousand at 27.5 percent. 5.4 plus 1.9 plus 1 plus 1.1 plus 0.583 is 9.983. The post does not print 9.983, and it does not print a Latin American total those rows could be checked against. 27 is not 27.5. 21 is not 25. The Asia Pacific floors on the same page are India more than 17 million at 28 percent, China more than 9 million at 10 percent, Indonesia more than 3.5 million at 23 percent, Japan more than 3.5 million at 23 percent, and the Philippines more than 1.7 million at 29 percent. 17 plus 9 plus 3.5 plus 3.5 plus 1.7 is 34.7. The post does not print 34.7. 34.7 is not 100, and 9.983 is not 34.7. Indonesia and Japan print the same 3.5 and the same 23. Same printed figures are not the same community. A floor is not a count. A count of other people's accounts is not the invitation on the repository you opened tonight.

Do the three proofs on one real invitation, in the repository that actually holds it. First, the binding. Copy the invitation id, the invitee login, the permission, and the url. Read the last path segment. If it is not the invitation id, write the integer that is actually there, and write that the sample's habit of putting 1296269 in an invitation url is not a reason to do the same with a live id. If expired is absent, write absent. Do not write false. If the response was 204, write 204, and write that no invitation id was stored. Second, the other invitation. A different id, even with the same login, is not this one. The organization example is that shape: id 1 again, login monalisa, email for octocat. A list that reprints the same id with a different node id is not a second invitation. It is one example disagreeing with itself. A developer census is not that second invitation. Third, the other repository. A list that belongs to someone else's repository does not contain this id. If the only list is one shared organization, write that. A client you cannot name is the finding.

Three moves feel like the proof and are a second problem. Cancelling the invitation because the login was embarrassing, and then describing the missing row as a cleanup. A 204 on a later delete is an empty body. It does not rewrite the id you failed to copy. Quoting 518 million or 5.2 billion because they look precise, while the invitation you were asked about is one object, and the post that printed them had already left 10.039 off the page. Asking a model which invite the repository sent. The model will pick a plausible login. It will not open the invitation. A person you have already added is which person did that repository add?. Opening that collaborator does not name this invitation id, and a permission of push on the add call is not the write the example stored.

The path is ordinary when an operator can open one client's invitations without opening the next client's invitations as the way to prove it. Cove is an operator portal, a headless CMS, and a marketing platform, consolidated into one operator experience. The shape that matters here is one client you can point at, in a repository the agency or the client can open, distinct from the next client. That case is not an invitation ledger. Nothing in that sentence is a headcount, a duration, or a result figure. If the only control on the screen changes every client's access together, you do not have this proof. You have a directory.

There is a version of this afternoon where the agency should not take the work. The work is not sold under the agency's name. The client asked to meet the builders. The room only has a slide. The buyer only wants a template. Or the buyer wants a legal opinion about what an invitation promises. A white label software development partner is the page for capacity sold under the agency's name. It does not rank anyone, including us. 518 million is not this repository, and id 1 on a sample is not this repository, and write is not push.

When the repository is real and the invitation is not on a screen you can open, the missing object is specific. The invitation id, the invitee, and the permission, a different invitation that is not that one, and another client's repository that does not list it. A white-label engagement that expects this will put the repository in the client's organization, or in yours, before the first push, because an invite that lives only in a vendor dashboard is not an id you can hand the client. One that can only paste a login into chat is telling you who holds the invite. Where the next slice is one capability and the acceptance sentence names the invitation id, an AI integration sprint is the shape that can require the three proofs as the definition of done. Where you are not sure which repository the current engagement uses, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that 5.2 billion contributions landed on this repository, and they are not id 1.

Before you tell the client which invite the repository sent, write the three lines. The invitation id, the invitee, and the permission, or the status code the response actually returned. A different invitation that is not that one. Another repository that does not hold it. Do not treat 1296269 as the invitation id because the sample url ends in it, and do not ask a model which login it was. A note can tell you that 5.2 billion divided by 518 million is 10.039, which the post does not print. The binding is the invitation you can defend.

Questions

Three records, in a repository the agency or the client can open. The invitation id, the invitee, and the permission, or a written line that no invitation was stored because the account was added without one. A different invitation whose id or invitee is not this one. Another client's repository that does not list this invitation. A 204 is not an invitation id, and a login is not a permission.

No. A count of other people's accounts is not the id on this invitation. An invitation you can defend is the id, the invitee, and the permission. 518 million projects is not invitation id 1, and write on a sample is not your permission.

When the work is not sold under the agency's name, when the client asked to meet the builders, when the room only has a slide, when the buyer only wants a template, or when the buyer wants a legal opinion.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→