See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
Three names, one reference
An Azure DevOps repository is addressed by organization, project, and repository. All three go into the stored reference, and any of them may legally contain interior spaces, which is why a project called BU - AMP is completely normal and completely fatal to a tool that assumed two path segments.
What the connection accepts is deliberately broad. The canonical org/project/repo form works. So does the browser URL with its _git segment, which is dropped. Percent-encoded segments are decoded, so BU%20-%20AMP becomes BU - AMP rather than a literal with percent signs in it. Legacy organization.visualstudio.com URLs are recognized, with the organization recovered from the subdomain and a leading DefaultCollection removed. A trailing .git and a version query string are stripped.
Validation is stricter than the paste rules, and on purpose. Interior spaces pass for Azure DevOps because the platform allows them, while tabs, newlines, control characters, traversal sequences, and anything that looks like a different host are rejected before a request is ever made.
All of these normalize to: Contoso/BU - AMP/platform-infra Contoso/BU - AMP/platform-infra https://dev.azure.com/Contoso/BU%20-%20AMP/_git/platform-infra dev.azure.com/Contoso/BU - AMP/_git/platform-infra https://Contoso.visualstudio.com/DefaultCollection/BU - AMP/_git/platform-infra https://dev.azure.com/Contoso/BU%20-%20AMP/_git/platform-infra?version=GBmain
The token, and the sign-in page that pretends to be data
Private repositories take a personal access token with the Code scope set to Read, the one Microsoft documents as vso.code: read source code and metadata about commits, branches, and other version control artifacts. It is sent as basic authentication with an empty username, which is the shape Azure DevOps expects, and it is validated by listing refs before anything is stored. Storage is encrypted, and only the last four characters are ever shown again.
Azure DevOps has an authentication behavior worth calling out, because it is where integrations usually break in a way nobody can debug. An unauthenticated request for a private resource does not return 401. It returns a 203 with an HTML sign-in page, or a redirect to the Microsoft sign-in host. A naive client parses that as JSON and reports a syntax error, which sends people hunting for the wrong problem.
Datadef classifies both shapes as what they are: the token is missing, expired, or issued for a different organization. A 401 or 403 means the token was presented and refused, so check the Code Read scope. A 404 means the organization, project, or repository name does not resolve for this token, so check the three names and their casing.
Refs are matched exactly
Every call the sync makes, and its API version
Four read endpoints, all pinned to api-version=7.1, which is the whole surface a security review has to look at. Refs are listed with a filter of heads or tags, tags with peelTags=true so an annotated tag resolves to the commit it wraps, and the listing follows the x-ms-continuationtoken response header for up to three pages of results.
The tree comes from items with recursionLevel=Full and a version descriptor pinned to the resolved commit id, capped at 20,000 entries. File content comes from the same items endpoint with includeContent=true and the same commit pin, so every file in one corpus is read at one commit rather than drifting across a push that lands mid-sync.
Each request has a 15 second timeout and a ceiling on the response body it will read. Nothing in that list writes: no pull request is opened, no status is posted, no pipeline is queued, and no work item is touched.
GET /refs?filter=heads&api-version=7.1 GET /refs?filter=tags&peelTags=true&api-version=7.1 GET /items?recursionLevel=Full&versionDescriptor.version=<sha>&versionDescriptor.versionType=commit GET /items?path=/<file>&includeContent=true&versionDescriptor.version=<sha>
What gets drawn from an Azure Repos project
The same reading pipeline as every other host: infrastructure as code first, then containers and orchestration, then data files, then API specs, then CI definitions, then dependency manifests, then prose. Up to 40 files and 250KB, with a count of every directory three levels deep so the shape of the untouched parts is still visible. The CI rule matches azure-pipelines.yml and its suffixed siblings, so azure-pipelines-infra.yml and azure-pipelines-deploy.yml are read too, up to 8 pipeline files.
The items API reports a size per entry, which Azure DevOps shares with GitHub and GitLab does not. That is worth one sentence because it changes the reading: anything over 400KB is dropped from the candidate list before a single byte is fetched, rather than being fetched and then discarded.
Terraform repositories take a dedicated path instead. Every .tf and .tfvars file is parsed, modules become zones, registry module calls keep their source and version, and per-environment counts come from the tfvars rather than from three cloned diagrams. Nothing is initialized, no state is read, and no Azure credentials are involved. The detail is in Azure Terraform diagram generator.
The output is a canvas plus an architecture.md, both regenerated on the daily sync and on demand. The diagram embeds in an Azure DevOps wiki page as a live image, which is covered in embed diagrams in an Azure DevOps wiki.
FAQ
Does an Azure DevOps project name with spaces work?
Which personal access token scope is required?
Why do Azure DevOps integrations often fail with a parsing error?
Can I paste the URL from my browser address bar?
Does it work with Azure DevOps Server hosted on our own network?